Compartir a través de


Registro de un evaluador de expresiones

Importante

En Visual Studio 2015, esta forma de implementar evaluadores de expresiones está en desuso. Para obtener información sobre cómo implementar evaluadores de expresiones CLR, vea Evaluadores de expresiones CLR y Ejemplo de evaluador de expresiones administradas.

El evaluador de expresiones (EE) debe registrarse como generador de clases con el entorno COM de Windows y Visual Studio. Un EE se configura como un archivo DLL para que se inserte en el espacio de direcciones del motor de depuración (DE) o en el espacio de direcciones de Visual Studio, en función de la entidad que cree una instancia de EE.

Evaluador de expresiones de código administrado

Un código administrado EE se implementa como una biblioteca de clases, que es un archivo DLL que se registra con el entorno COM, normalmente iniciado por una llamada al programa VSIP, regpkg.exe. El proceso real de escribir las claves del Registro para el entorno COM se controla automáticamente.

Un método de la clase principal se marca con ComRegisterFunctionAttribute, lo que indica que se va a llamar al método cuando se registra el archivo DLL con COM. Este método de registro, a menudo denominado RegisterClass, realiza la tarea de registrar el archivo DLL con Visual Studio. UnregisterClass Correspondiente (marcado con ), ComUnregisterFunctionAttributedeshace los efectos de RegisterClass cuando se desinstala el archivo DLL. Las mismas entradas del Registro se realizan para un EE escrito en código no administrado; la única diferencia es que no hay ninguna función auxiliar como SetEEMetric para realizar el trabajo por usted. A continuación se muestra un ejemplo del proceso de registro y anulación del registro.

Ejemplo

La siguiente función muestra cómo un código administrado EE registra y anula el registro con 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);
            }
        }
    }
}

Evaluador de expresiones de código no administradas

La DLL de EE implementa la DllRegisterServer función para registrarse en el entorno COM, así como en Visual Studio.

Nota:

Puede encontrar el código del Registro de ejemplo de código myCEE en el archivo dllentry.cpp, que se encuentra en la instalación de VSIP en EnVSDK\MyCPkgs\MyCEE.

Proceso del servidor DLL

Al registrar el EE, el servidor DLL:

  1. Registra su generador CLSID de clases según las convenciones COM normales.

  2. Llama a la función SetEEMetric auxiliar para registrarse con Visual Studio las métricas ee que se muestran en la tabla siguiente. La función SetEEMetric y las métricas especificadas como se indica a continuación forman parte de la biblioteca dbgmetric.lib . Consulte asistentes del SDK para la depuración para obtener más información.

    Métrica Descripción
    metricCLSID CLSID del generador de clases EE
    metricName Nombre de EE como una cadena que se puede mostrar
    metricLanguage Nombre del idioma que el EE está diseñado para evaluar
    metricEngine GUIDde los motores de depuración (DE) que funcionan con esta EE

    Nota:

    metricLanguage``GUID identifica el idioma por nombre, pero es el guidLang argumento para SetEEMetric que seleccione el idioma. Cuando el compilador genera el archivo de información de depuración, debe escribir lo adecuado guidLang para que el DE sepa qué EE usar. El DE normalmente solicita al proveedor de símbolos este idioma GUID, que se almacena en el archivo de información de depuración.

  3. Se registra con Visual Studio mediante la creación de claves en HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\X.Y, donde X.Y es la versión de Visual Studio con la que registrarse.

Ejemplo

La función siguiente muestra cómo un código no administrado (C++) EE registra y anula el registro con 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;
}