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:
Registra su generador
CLSID
de clases según las convenciones COM normales.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ónSetEEMetric
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 EEmetricName
Nombre de EE como una cadena que se puede mostrar metricLanguage
Nombre del idioma que el EE está diseñado para evaluar metricEngine
GUID
de los motores de depuración (DE) que funcionan con esta EENota:
metricLanguage``GUID
identifica el idioma por nombre, pero es elguidLang
argumento paraSetEEMetric
que seleccione el idioma. Cuando el compilador genera el archivo de información de depuración, debe escribir lo adecuadoguidLang
para que el DE sepa qué EE usar. El DE normalmente solicita al proveedor de símbolos este idiomaGUID
, que se almacena en el archivo de información de depuración.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;
}