Compartilhar via


Registrar um avaliador de expressão

Importante

No Visual Studio 2015, essa forma de implementar avaliadores de expressão é 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 se registrar como uma classe fábrica tanto no ambiente COM do Windows quanto no Visual Studio. Um EE é configurado como uma DLL para ser injetado no espaço de endereçamento do motor de depuração (DE) ou no espaço de endereçamento 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 no ambiente COM, normalmente iniciada 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 ComRegisterFunctionAttribute, indicando que o método deve ser chamado quando a DLL está sendo registrada com COM. Esse método de registro, geralmente chamado RegisterClass, executa a tarefa de registrar a DLL no Visual Studio. Um correspondente UnregisterClass (marcado com o ComUnregisterFunctionAttribute), desfaz os efeitos de RegisterClass quando a DLL é desinstalada. As mesmas entradas do Registro são feitas como para um EE escrito em código não gerenciado; a única diferença é que não há nenhuma função auxiliar, como SetEEMetric, que faça o trabalho para você. Veja a seguir um exemplo do processo de registro e cancelamento de registro.

Example

A função a seguir mostra como um EE de código gerenciado se registra e cancela o registro no 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 do EE implementa a DllRegisterServer função para se registrar no ambiente COM, bem como no Visual Studio.

Observação

Você pode encontrar o código do registro de exemplo de código MyCEE 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 fábrica CLSID de classes de acordo com as convenções COM normais.

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

    Métrica Description
    metricCLSID CLSID da fábrica de classes do EE
    metricName Nome do EE como uma string 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 ambiente de execução (EE)

    Observação

    Identifica o idioma pelo nome através de metricLanguage``GUID, mas é o argumento guidLang para SetEEMetric que seleciona o idioma. Quando o compilador gera o arquivo de informações de depuração, ele deve gravar o elemento apropriado guidLang para que o DE saiba qual EE deve 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 no Visual Studio criando chaves em HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\X.Y, em que o X.Y é a versão do Visual Studio com a qual se registrar.

Example

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