Partager via


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 :

  1. Inscrit sa fabrique CLSID de classes conformément aux conventions COM normales.

  2. 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 fonction SetEEMetric 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 EE
    metricName Nom de l’EE en tant que chaîne affichable
    metricLanguage Nom de la langue que l’EE est conçue pour évaluer
    metricEngine GUIDdes moteurs de débogage (DE) qui fonctionnent avec cet EE

    Remarque

    Identifie metricLanguage``GUID la langue par nom, mais il s’agit de l’argument guidLang qui SetEEMetric 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 langue GUID, qui est stocké dans le fichier d’informations de débogage.

  3. 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;
}