Registrare un analizzatore di espressioni
Importante
In Visual Studio 2015 questo modo di implementare gli analizzatori di espressioni è deprecato. Per informazioni sull'implementazione degli analizzatori di espressioni CLR, vedere l'esempio degli analizzatori di espressioni CLR e dell'analizzatore di espressioni gestite.
L'analizzatore di espressioni (edizione Enterprise) deve registrarsi come class factory sia con l'ambiente COM di Windows che con Visual Studio. Un edizione Enterprise viene configurato come DLL in modo che venga inserito nello spazio indirizzi del motore di debug (DE) o nello spazio indirizzi di Visual Studio, a seconda dell'entità di cui crea un'istanza del edizione Enterprise.
Analizzatore di espressioni di codice gestito
Un codice gestito edizione Enterprise viene implementato come libreria di classi, ovvero una DLL che si registra con l'ambiente COM, in genere avviata da una chiamata al programma VSIP, regpkg.exe. Il processo effettivo di scrittura delle chiavi del Registro di sistema per l'ambiente COM viene gestito automaticamente.
Un metodo della classe main è contrassegnato con ComRegisterFunctionAttribute, che indica che il metodo deve essere chiamato quando la DLL viene registrata con COM. Questo metodo di registrazione, spesso chiamato RegisterClass
, esegue l'attività di registrazione della DLL con Visual Studio. Un oggetto corrispondente UnregisterClass
(contrassegnato con ), ComUnregisterFunctionAttributeannulla gli effetti di RegisterClass
quando la DLL viene disinstallata.
Le stesse voci del Registro di sistema vengono eseguite come per un edizione Enterprise scritto in codice non gestito. L'unica differenza è che non esiste alcuna funzione helper, SetEEMetric
ad esempio per eseguire il lavoro. Di seguito è riportato un esempio del processo di registrazione e annullamento della registrazione.
Esempio
La funzione seguente illustra come un codice gestito edizione Enterprise registra e annulla la registrazione con Visual Studio.
namespace EEMC
{
[GuidAttribute("462D4A3D-B257-4AEE-97CD-5918C7531757")]
public class EEMCClass : IDebugExpressionEvaluator
{
#region Register and unregister.
private static Guid guidMycLang = new Guid("462D4A3E-B257-4AEE-97CD-5918C7531757");
private static string languageName = "MyC";
private static string eeName = "MyC Expression Evaluator";
private static Guid guidMicrosoftVendor = new Guid("994B45C4-E6E9-11D2-903F-00C04FA302A1");
private static Guid guidCOMPlusOnlyEng = new Guid("449EC4CC-30D2-4032-9256-EE18EB41B62B");
private static Guid guidCOMPlusNativeEng = new Guid("92EF0900-2251-11D2-B72E-0000F87572EF");
/// <summary>
/// Register the expression evaluator.
/// Set "project properties/configuration properties/build/register for COM interop" to true.
/// </summary>
[ComRegisterFunctionAttribute]
public static void RegisterClass(Type t)
{
// Get Visual Studio version (set by regpkg.exe)
string hive = Environment.GetEnvironmentVariable("EnvSdk_RegKey");
string s = @"SOFTWARE\Microsoft\VisualStudio\"
+ hive
+ @"\AD7Metrics\ExpressionEvaluator";
RegistryKey rk = Registry.LocalMachine.CreateSubKey(s);
if (rk == null) return;
rk = rk.CreateSubKey(guidMycLang.ToString("B"));
rk = rk.CreateSubKey(guidMicrosoftVendor.ToString("B"));
rk.SetValue("CLSID", t.GUID.ToString("B"));
rk.SetValue("Language", languageName);
rk.SetValue("Name", eeName);
rk = rk.CreateSubKey("Engine");
rk.SetValue("0", guidCOMPlusOnlyEng.ToString("B"));
rk.SetValue("1", guidCOMPlusNativeEng.ToString("B"));
}
/// <summary>
/// Unregister the expression evaluator.
/// </summary>
[ComUnregisterFunctionAttribute]
public static void UnregisterClass(Type t)
{
// Get Visual Studio version (set by regpkg.exe)
string hive = Environment.GetEnvironmentVariable("EnvSdk_RegKey");
string s = @"SOFTWARE\Microsoft\VisualStudio\"
+ hive
+ @"\AD7Metrics\ExpressionEvaluator\"
+ guidMycLang.ToString("B");
RegistryKey key = Registry.LocalMachine.OpenSubKey(s);
if (key != null)
{
key.Close();
Registry.LocalMachine.DeleteSubKeyTree(s);
}
}
}
}
Analizzatore di espressioni di codice non gestite
La DLL edizione Enterprise implementa la DllRegisterServer
funzione per registrarsi con l'ambiente COM e Visual Studio.
Nota
È possibile trovare il codice del Registro di sistema myC edizione Enterprise di esempio di codice nel file dllentry.cpp, che si trova nell'installazione di VSIP in EnVSDK\MyCPkgs\MyC edizione Enterprise.
Processo del server DLL
Quando si registra il edizione Enterprise, il server DLL:
Registra la class factory
CLSID
in base alle normali convenzioni COM.Chiama la funzione
SetEEMetric
helper per la registrazione con Visual Studio le metriche edizione Enterprise illustrate nella tabella seguente. La funzioneSetEEMetric
e le metriche specificate di seguito fanno parte della libreria dbgmetric.lib . Per informazioni dettagliate, vedere Helper SDK per il debug .Metrico Descrizione metricCLSID
CLSID
della class factory di edizione EnterprisemetricName
Nome del edizione Enterprise come stringa visualizzabile metricLanguage
Nome della lingua che il edizione Enterprise è progettato per valutare metricEngine
GUID
s dei motori di debug (DE) che funzionano con questo edizione EnterpriseNota
metricLanguage``GUID
Identifica la lingua in base al nome, ma è l'argomentoguidLang
aSetEEMetric
che seleziona la lingua. Quando il compilatore genera il file di informazioni di debug, deve scrivere l'elemento appropriatoguidLang
in modo che DE conosca quale edizione Enterprise usare. De richiede in genere al provider di simboli questo linguaggio , che viene archiviatoGUID
nel file di informazioni di debug.Esegue la registrazione con Visual Studio creando chiavi in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\X.Y, dove X.Y è la versione di Visual Studio con cui eseguire la registrazione.
Esempio
La funzione seguente illustra come un codice non gestito (C++) edizione Enterprise registra e annulla la registrazione con Visual Studio.
/*---------------------------------------------------------
Registration
-----------------------------------------------------------*/
#ifndef LREGKEY_VISUALSTUDIOROOT
#define LREGKEY_VISUALSTUDIOROOT L"Software\\Microsoft\\VisualStudio\\8.0"
#endif
static HRESULT RegisterMetric( bool registerIt )
{
// check where we should register
const ULONG cchBuffer = _MAX_PATH;
WCHAR wszRegistrationRoot[cchBuffer];
DWORD cchFreeBuffer = cchBuffer - 1;
wcscpy(wszRegistrationRoot, LREGKEY_VISUALSTUDIOROOT_NOVERSION);
wcscat(wszRegistrationRoot, L"\\");
// this is Environment SDK specific
// we check for EnvSdk_RegKey environment variable to
// determine where to register
DWORD cchDefRegRoot = lstrlenW(LREGKEY_VISUALSTUDIOROOT_NOVERSION) + 1;
cchFreeBuffer = cchFreeBuffer - cchDefRegRoot;
DWORD cchEnvVarRead = GetEnvironmentVariableW(
/* LPCTSTR */ L"EnvSdk_RegKey", // environment variable name
/* LPTSTR */ &wszRegistrationRoot[cchDefRegRoot],// buffer for variable value
/* DWORD */ cchFreeBuffer);// size of buffer
if (cchEnvVarRead >= cchFreeBuffer)
return E_UNEXPECTED;
// If the environment variable does not exist then we must use
// LREGKEY_VISUALSTUDIOROOT which has the version number.
if (0 == cchEnvVarRead)
wcscpy(wszRegistrationRoot, LREGKEY_VISUALSTUDIOROOT);
if (registerIt)
{
SetEEMetric(guidMycLang,
guidMicrosoftVendor,
metricCLSID,
CLSID_MycEE,
wszRegistrationRoot );
SetEEMetric(guidMycLang,
guidMicrosoftVendor,
metricName,
GetString(IDS_INFO_MYCDESCRIPTION),
wszRegistrationRoot );
SetEEMetric(guidMycLang,
guidMicrosoftVendor,
metricLanguage, L"MyC",
wszRegistrationRoot);
GUID engineGuids[2];
engineGuids[0] = guidCOMPlusOnlyEng;
engineGuids[1] = guidCOMPlusNativeEng;
SetEEMetric(guidMycLang,
guidMicrosoftVendor,
metricEngine,
engineGuids,
2,
wszRegistrationRoot);
}
else
{
RemoveEEMetric( guidMycLang,
guidMicrosoftVendor,
metricCLSID,
wszRegistrationRoot);
RemoveEEMetric( guidMycLang,
guidMicrosoftVendor,
metricName,
wszRegistrationRoot );
RemoveEEMetric( guidMycLang,
guidMicrosoftVendor,
metricLanguage,
wszRegistrationRoot );
RemoveEEMetric( guidMycLang,
guidMicrosoftVendor,
metricEngine,
wszRegistrationRoot );
}
return S_OK;
}