Partilhar via


Registrando um avaliador de expressão

O avaliador de expressão (EE) deve ser registrado como uma fábrica de classes com o ambiente COM Windows e o Visual Studio. Um EE é implementado como uma DLL para que ele pode ser injetado o espaço de endereço do mecanismo (DE) de depuração ou o espaço de endereço de Visual Studio, dependendo de qual entidade instancia o EE.

Avaliador de expressão de código gerenciado

Um código gerenciado EE é implementado como uma biblioteca de classe, que é uma DLL que se registra com o ambiente COM, geralmente, iniciado por uma chamada para o programa VSIP, regpkg.exe. O processo real de escrever as chaves do registro para o ambiente de COM será processado automaticamente.

Um método da classe principal é marcado com o ComRegisterFunctionAttribute, indicando que esse método é para ser chamado quando a DLL que está sendo registrada com COM. Esse método de registro, muitas vezes chamado RegisterClass, executa a tarefa de registrar a DLL com 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 para um EE escrito em código não gerenciado; a única diferença é que não há nenhuma função de auxiliar, como SetEEMetric para fazer o trabalho para você. Um exemplo desse processo de cancelamento de registro/registro tem esta aparência:

Exemplo

Esta função mostra como um código gerenciado EE registra e cancela o registro propriamente dito com 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 o DllRegisterServer função para se registrar com o ambiente COM bem como Visual Studio.

Dica

O código de registro do exemplo de código MyCEE encontra-se em dllentry.cpp o arquivo, que está localizado na instalação do VSIP em EnVSDK\MyCPkgs\MyCEE.

Processo de DLL do servidor

Ao registrar o EE, o servidor DLL:

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

  2. Chama a função auxiliar SetEEMetric para registrar com 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. Para obter detalhes, consulte:SDK auxiliares para depuração

    Métrica

    Descrição

    metricCLSID

    CLSIDda fábrica de classe EE

    metricName

    Nome da EE como uma seqüência de exibição

    metricLanguage

    O nome do idioma que o EE é projetado para avaliar

    metricEngine

    GUIDs dos mecanismos de depuração (DE) que funcionam com este EE

    Dica

    O metricLanguageGUID identifica o idioma pelo nome, mas ele é o guidLang argumento para SetEEMetric que seleciona o 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 para usar.O DE pede o provedor de símbolo para este idioma GUID, que é armazenada no arquivo de informações de depuração.

  3. Registra com Visual Studio com a criação de chaves em HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\x. y, onde x. y é a versão do Visual Studio para registrar.

Exemplo

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

Consulte também

Referência

SDK auxiliares para depuração

Outros recursos

Escrevendo um avaliador da expressão em tempo de execução de linguagem comum