Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
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'il soit injecté dans l’espace d’adressage du moteur de débogage (DE) ou dans l’espace d’adressage de Visual Studio, selon l’entité qui l’instancie.
É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 UnregisterClass correspondant (marqué avec le ComUnregisterFunctionAttribute) annule les effets de RegisterClass lors de la désinstallation de 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, telle que SetEEMetric, pour effectuer cette tâche. Voici un exemple de processus d’inscription et d’annulation de l’inscription.
Example
La fonction suivante montre comment un EE de code managé s'enregistre et se désenregistre dans 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.
Note
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
CLSIDde classes conformément aux conventions COM normales.Appelle la fonction d'assistance
SetEEMetricpour enregistrer auprès de Visual Studio les métriques ÉE présentées dans le tableau suivant. La fonctionSetEEMetricet les métriques spécifiées comme suit font partie de la bibliothèque dbgmetric.lib . Pour plus d’informations, consultez les assistants du Kit de développement logiciel (SDK) pour le débogage.Unité de mesure Descriptif metricCLSIDCLSIDde l'usine de classes EEmetricNameNom de l’EE sous forme de chaîne affichable metricLanguageNom de la langue que l’EE est conçue pour évaluer metricEngineGUIDdes moteurs de débogage (DE) qui fonctionnent avec cet EENote
Le
metricLanguage``GUIDidentifie la langue par son nom, mais c'est l'argumentguidLangdeSetEEMetricqui sélectionne la langue. Lorsque le compilateur génère le fichier d’informations de débogage, il doit écrire le fichier appropriéguidLangafin 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.
Example
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;
}