Registrar um avaliador de expressão

Importante

No Visual Studio 2015, essa maneira de implementar avaliadores de expressão foi preterida. Para obter informações sobre como implementar avaliadores de expressão CLR, consulte Avaliadores de expressão CLR e Exemplo de avaliador de expressão gerenciada.

O avaliador de expressão (EE) deve registrar-se como uma fábrica de classe com o ambiente COM do Windows e o Visual Studio. Um EE é configurado como uma DLL para que seja injetado no espaço de endereço do mecanismo de depuração (DE) ou no espaço de endereço do Visual Studio, dependendo de qual entidade instancia o EE.

Avaliador de expressão de código gerenciado

Um EE de código gerenciado é implementado como uma biblioteca de classes, que é uma DLL que se registra com o ambiente COM, normalmente iniciado por uma chamada para o programa VSIP, regpkg.exe. O processo real de gravação das chaves do Registro para o ambiente COM é tratado automaticamente.

Um método da classe principal é marcado com , indicando que o método deve ser chamado quando a DLL está sendo registrada com ComRegisterFunctionAttributeCOM. Esse método de registro, geralmente chamado RegisterClass, executa a tarefa de registrar a DLL com o Visual Studio. Um correspondente UnregisterClass (marcado com o ComUnregisterFunctionAttribute), desfaz os efeitos de RegisterClass quando a DLL é desinstalada. As mesmas entradas de registro são feitas como para um EE escrito em código não gerenciado; A única diferença é que não há uma função auxiliar como SetEEMetric fazer o trabalho para você. A seguir está um exemplo do processo de registro e cancelamento de registro.

Exemplo

A função a seguir mostra como um EE de código gerenciado registra e cancela o registro com o 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);
            }
        }
    }
}

Avaliador de expressão de código não gerenciado

A DLL EE implementa a DllRegisterServer função para registrar-se com o ambiente COM, bem como Visual Studio.

Observação

Você pode encontrar o código MyCEE exemplo código do Registro no arquivo dllentry.cpp, que está localizado na instalação do VSIP em EnVSDK\MyCPkgs\MyCEE.

Processo do servidor DLL

Ao registrar o EE, o servidor DLL:

  1. Registra sua classe de fábrica de CLSID acordo com as convenções COM normais.

  2. Chama a função SetEEMetric auxiliar para registrar com o Visual Studio as métricas EE mostradas na tabela a seguir. A função SetEEMetric e as métricas especificadas a seguir fazem parte da biblioteca dbgmetric.lib . Consulte Auxiliares do SDK para depuração para obter detalhes.

    Métrica Descrição
    metricCLSID CLSID da fábrica da classe EE
    metricName Nome do EE como uma cadeia de caracteres exibível
    metricLanguage O nome do idioma que o EE foi projetado para avaliar
    metricEngine GUIDs dos mecanismos de depuração (DE) que funcionam com este EE

    Observação

    O metricLanguage``GUID identifica o idioma pelo nome, mas é o argumento para SetEEMetric que seleciona o guidLang idioma. Quando o compilador gera o arquivo de informações de depuração, ele deve gravar o apropriado guidLang para que o DE saiba qual EE usar. O DE normalmente solicita ao provedor de símbolos esse idioma GUID, que é armazenado no arquivo de informações de depuração.

  3. Registra-se com o Visual Studio criando chaves em HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\X.Y, onde X.Y é a versão do Visual Studio com a qual se registrar.

Exemplo

A função a seguir mostra como um código não gerenciado (C++) EE registra e cancela o registro com o 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;
}