Udostępnij przez


Rejestrowanie ewaluatora wyrażeń

Ważne

W programie Visual Studio 2015 ten sposób implementowania ewaluatorów wyrażeń jest przestarzały. Aby uzyskać informacje na temat implementowania ewaluatorów wyrażeń CLR, zobacz ewaluatory wyrażeń CLR oraz przykład ewaluatora wyrażeń zarządzanych.

Ewaluator wyrażeń (EE) musi zarejestrować się jako fabryka klas zarówno w środowisku Windows COM, jak i w programie Visual Studio. EE jest skonfigurowana jako biblioteka DLL, aby mogła zostać wstrzyknięta do przestrzeni adresowej aparatu debugowania (DE) lub przestrzeni adresowej programu Visual Studio, w zależności od tego, która jednostka inicjuje instancję EE.

Ewaluator wyrażeń kodu zarządzanego

Kod zarządzany EE jest implementowany jako biblioteka klas, która jest biblioteką DLL rejestrującą się w środowisku COM, zwykle uruchamianą przez wywołanie programu VSIP, regpkg.exe. Rzeczywisty proces zapisywania kluczy rejestru dla środowiska COM jest obsługiwany automatycznie.

Metoda klasy głównej jest oznaczona znakiem ComRegisterFunctionAttribute, wskazując, że metoda ma być wywoływana, gdy biblioteka DLL jest zarejestrowana w modelu COM. Ta metoda rejestracji, często nazywana RegisterClass, wykonuje zadanie rejestrowania biblioteki DLL w programie Visual Studio. Odpowiedni UnregisterClass element (oznaczony symbolem ComUnregisterFunctionAttribute), cofa efekty RegisterClass po odinstalowaniu biblioteki DLL. Te same wpisy rejestru są tworzone jak dla EE napisanego w kodzie niezarządzanym; jedyną różnicą jest to, że nie ma funkcji pomocniczej, takiej jak SetEEMetric, która wykonuje pracę za Ciebie. Poniżej przedstawiono przykład procesu rejestracji i wyrejestrowania.

Example

Poniższa funkcja pokazuje, jak zarządzany kod EE rejestruje się i wyrejestrowuje się w programie 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);
            }
        }
    }
}

Niezarządzany ewaluator wyrażeń kodu

Biblioteka DLL EE implementuje funkcję DllRegisterServer, aby się zarejestrować w środowisku COM oraz w programie Visual Studio.

Uwaga / Notatka

Przykładowy kod kodu MyCEE można znaleźć w pliku dllentry.cpp, który znajduje się w instalacji programu VSIP w obszarze EnVSDK\MyCPkgs\MyCEE.

Proces serwera DLL

Podczas rejestrowania EE serwer DLL:

  1. Rejestruje swoją klasową fabrykę CLSID zgodnie z typowymi dla COM konwencjami.

  2. Wywołuje funkcję SetEEMetric pomocnika w celu zarejestrowania w programie Visual Studio metryk EE przedstawionych w poniższej tabeli. Funkcja SetEEMetric i metryki określone w następujący sposób są częścią biblioteki dbgmetric.lib . Zobacz Pomocników SDK do debugowania w celu uzyskania szczegółowych informacji.

    Wskaźnik Description
    metricCLSID CLSID fabryki klasy EE
    metricName Nazwa EE jako ciąg, który można wyświetlić
    metricLanguage Nazwa języka, który ma być oceniany przez EE
    metricEngine GUIDs mechanizmów debugowania (DE), które współpracują z tym EE

    Uwaga / Notatka

    Element metricLanguage``GUID identyfikuje język według nazwy, ale argument guidLang w SetEEMetric to ten, który wybiera język. Gdy kompilator generuje plik informacji o debugowaniu, powinien zapisać odpowiedni guidLang, aby DE wiedział, którego EE użyć. DE zazwyczaj prosi dostawcę symboli dla tego języka GUID, które są przechowywane w pliku informacji o debugowaniu.

  3. Rejestruje się w programie Visual Studio, tworząc klucze w HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\X.Y, gdzie X.Y jest wersją programu Visual Studio do zarejestrowania.

Example

Poniższa funkcja pokazuje, jak niezarządzany kod (C++) EE rejestruje się i wyrejestrowuje się w programie 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;
}