Rejestrowanie ewaluatora wyrażeń
Ważne
W programie Visual Studio 2015 ten sposób implementowania ewaluatorów wyrażeń jest przestarzały. Aby uzyskać informacje na temat implementowania ewaluatorów wyrażeń CLR, zobacz clR expression evaluators and Managed expression evaluator sample (Przykład ewaluatora wyrażeń zarządzanych).
Ewaluator wyrażeń (EE) musi zarejestrować się jako fabryka klas zarówno w środowisku Windows COM, jak i w programie Visual Studio. EE jest konfigurowana jako biblioteka DLL, tak aby została wstrzyknięta do przestrzeni adresowej aparatu debugowania (DE) lub przestrzeni adresowej programu Visual Studio, w zależności od tego, która jednostka tworzy wystąpienie środowiska EE.
Ewaluator wyrażeń kodu zarządzanego
Kod zarządzany EE jest implementowany jako biblioteka klas, która jest biblioteką DLL, która rejestruje się w środowisku COM, zazwyczaj uruchamiane przez wywołanie programu VSIP, regpkg.exe. Rzeczywisty proces zapisywania kluczy rejestru dla środowiska COM jest obsługiwany automatycznie.
Metoda klasy głównej jest oznaczona znakiem ComRegisterFunctionAttribute, wskazując, że metoda ma być wywoływana, gdy biblioteka DLL jest zarejestrowana w modelu COM. Ta metoda rejestracji, często nazywana RegisterClass
, wykonuje zadanie rejestrowania biblioteki DLL w programie Visual Studio. Odpowiedni UnregisterClass
element (oznaczony symbolem ComUnregisterFunctionAttribute), cofa efekty RegisterClass
po odinstalowaniu biblioteki DLL.
Te same wpisy rejestru są tworzone jako dla EE napisanego w kodzie niezarządzanym; Jedyną różnicą jest to, że nie ma funkcji pomocniczej, takiej jak SetEEMetric
wykonywanie pracy dla Ciebie. Poniżej przedstawiono przykład procesu rejestracji i wyrejestrowania.
Przykład
Poniższa funkcja pokazuje, jak zarządzany kod EE rejestruje się i wyrejestrowuje się w programie 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);
}
}
}
}
Niezarządzany ewaluator wyrażeń kodu
Biblioteka DLL EE implementuje DllRegisterServer
funkcję, aby zarejestrować się w środowisku COM, a także w programie Visual Studio.
Uwaga
Przykładowy kod kodu MyCEE można znaleźć w pliku dllentry.cpp, który znajduje się w instalacji vsIP w obszarze EnVSDK\MyCPkgs\MyCEE.
Proces serwera DLL
Podczas rejestrowania EE serwer DLL:
Rejestruje swoją fabrykę
CLSID
klas zgodnie z normalnymi konwencjami COM.Wywołuje funkcję
SetEEMetric
pomocnika w celu zarejestrowania w programie Visual Studio metryk EE przedstawionych w poniższej tabeli. FunkcjaSetEEMetric
i metryki określone w następujący sposób są częścią biblioteki dbgmetric.lib . Aby uzyskać szczegółowe informacje, zobacz Pomocnicy zestawu SDK, aby uzyskać szczegółowe informacje.Metryczne opis metricCLSID
CLSID
fabryki klas EEmetricName
Nazwa EE jako ciąg z możliwością wyświetlania metricLanguage
Nazwa języka, który ma być obliczany przez EE metricEngine
GUID
s aparatów debugowania (DE), które współpracują z tym EEUwaga
Element
metricLanguage``GUID
identyfikuje język według nazwy, ale jestguidLang
to argumentSetEEMetric
, który wybiera język. Gdy kompilator generuje plik informacji o debugowaniu, powinien zapisać odpowiedniguidLang
kod, aby de wiedział, którego środowiska EE użyć. De zwykle pyta dostawcę symboli dla tego językaGUID
, który jest przechowywany w pliku informacji o debugowaniu.Rejestruje się w programie Visual Studio, tworząc klucze w folderze HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\X.Y, gdzie X.Y jest wersją programu Visual Studio do zarejestrowania.
Przykład
Poniższa funkcja pokazuje, jak niezarządzany kod (C++) EE rejestruje się i wyrejestrowuje się w programie 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;
}