Udostępnij za pośrednictwem


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 clR expression evaluators and Managed expression evaluator sample (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 konfigurowana jako biblioteka DLL, tak aby została wstrzyknięta do przestrzeni adresowej aparatu debugowania (DE) lub przestrzeni adresowej programu Visual Studio, w zależności od tego, która jednostka tworzy wystąpienie środowiska EE.

Ewaluator wyrażeń kodu zarządzanego

Kod zarządzany EE jest implementowany jako biblioteka klas, która jest biblioteką DLL, która rejestruje się w środowisku COM, zazwyczaj uruchamiane 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 jako dla EE napisanego w kodzie niezarządzanym; Jedyną różnicą jest to, że nie ma funkcji pomocniczej, takiej jak SetEEMetric wykonywanie pracy dla Ciebie. Poniżej przedstawiono przykład procesu rejestracji i wyrejestrowania.

Przykład

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 DllRegisterServer funkcję, aby zarejestrować się w środowisku COM, a także w programie Visual Studio.

Uwaga

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

Proces serwera DLL

Podczas rejestrowania EE serwer DLL:

  1. Rejestruje swoją fabrykę CLSID klas zgodnie z normalnymi konwencjami COM.

  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 . Aby uzyskać szczegółowe informacje, zobacz Pomocnicy zestawu SDK, aby uzyskać szczegółowe informacje.

    Metryczne opis
    metricCLSID CLSID fabryki klas EE
    metricName Nazwa EE jako ciąg z możliwością wyświetlania
    metricLanguage Nazwa języka, który ma być obliczany przez EE
    metricEngine GUIDs aparatów debugowania (DE), które współpracują z tym EE

    Uwaga

    Element metricLanguage``GUID identyfikuje język według nazwy, ale jest guidLang to argument SetEEMetric , który wybiera język. Gdy kompilator generuje plik informacji o debugowaniu, powinien zapisać odpowiedni guidLang kod, aby de wiedział, którego środowiska EE użyć. De zwykle pyta dostawcę symboli dla tego języka GUID, który jest przechowywany w pliku informacji o debugowaniu.

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

Przykład

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