Inscrire un évaluateur d’expression
Important
Dans Visual Studio 2015, cette façon d’implémenter des évaluateurs d’expression est déconseillée. Pour plus d’informations sur l’implémentation d’évaluateurs d’expression CLR, consultez l’exemple d’évaluateur d’expression CLR et d’évaluateur d’expression managée.
L’évaluateur d’expression (EE) doit s’inscrire en tant que fabrique de classes avec l’environnement COM Windows et Visual Studio. Un EE est configuré en tant que DLL afin qu’elle soit injectée dans l’espace d’adressage du moteur de débogage (DE) ou dans l’espace d’adressage Visual Studio, selon l’entité instancie l’EE.
Évaluateur d’expression de code managé
Un environnement EE de code managé est implémenté en tant que bibliothèque de classes, qui est une DLL qui s’inscrit auprès de l’environnement COM, généralement démarrée par un appel au programme VSIP, regpkg.exe. Le processus réel d’écriture des clés de Registre pour l’environnement COM est géré automatiquement.
Une méthode de la classe principale est marquée avec ComRegisterFunctionAttribute, indiquant que la méthode doit être appelée lorsque la DLL est inscrite auprès de COM. Cette méthode d’inscription, souvent appelée RegisterClass
, effectue la tâche d’inscription de la DLL auprès de Visual Studio. Un correspondant UnregisterClass
(marqué avec le ComUnregisterFunctionAttribute), annule les effets de la désinstallation de RegisterClass
la DLL.
Les mêmes entrées de Registre sont effectuées que pour un EE écrit dans du code non managé ; la seule différence est qu’il n’existe aucune fonction d’assistance, par SetEEMetric
exemple pour effectuer le travail pour vous. Voici un exemple de processus d’inscription et d’annulation de l’inscription.
Exemple
La fonction suivante montre comment un EE de code managé inscrit et désinscrit lui-même avec 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);
}
}
}
}
Évaluateur d’expression de code non managé
La DLL EE implémente la DllRegisterServer
fonction pour s’inscrire auprès de l’environnement COM ainsi que Visual Studio.
Remarque
Vous trouverez l’exemple de code MyCEE dans le fichier dllentry.cpp, qui se trouve dans l’installation de VSIP sous EnVSDK\MyCPkgs\MyCEE.
Processus du serveur DLL
Lors de l’inscription de l’EE, le serveur DLL :
Inscrit sa fabrique
CLSID
de classes conformément aux conventions COM normales.Appelle la fonction
SetEEMetric
d’assistance pour s’inscrire auprès de Visual Studio les métriques EE indiquées dans le tableau suivant. La fonctionSetEEMetric
et les métriques spécifiées comme suit font partie de la bibliothèque dbgmetric.lib . Pour plus d’informations, consultez les helpers du Kit de développement logiciel (SDK) pour plus d’informations.Métrique Description metricCLSID
CLSID
de la fabrique de classes EEmetricName
Nom de l’EE en tant que chaîne affichable metricLanguage
Nom de la langue que l’EE est conçue pour évaluer metricEngine
GUID
des moteurs de débogage (DE) qui fonctionnent avec cet EERemarque
Identifie
metricLanguage``GUID
la langue par nom, mais il s’agit de l’argumentguidLang
quiSetEEMetric
sélectionne la langue. Lorsque le compilateur génère le fichier d’informations de débogage, il doit écrire le fichier appropriéguidLang
afin que le DE sache quel EE utiliser. Le DE demande généralement le fournisseur de symboles pour cette langueGUID
, qui est stocké dans le fichier d’informations de débogage.S’inscrit auprès de Visual Studio en créant des clés sous HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\X.Y, où X.Y est la version de Visual Studio à inscrire.
Exemple
La fonction suivante montre comment un code non managé (C++) EE inscrit et désinscrit lui-même avec 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;
}