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:
Registra sua fábrica de classes CLSID de acordo com as convenções normais de COM.
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.
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
Outros recursos
Escrevendo um avaliador da expressão em tempo de execução de linguagem comum