註冊的運算式評估工具
運算式評估工具 (EE) 必須登錄本身為類別工廠使用 Windows COM 環境和 Visual Studio。 EE 會實作為 DLL 中,使它可以插入偵錯引擎 (DE) 地址空間或 Visual Studio 的位址空間,取決於實體執行個體化 EE。
Managed 程式碼運算式評估工具
EE 都會實作成類別程式庫,也就是會將自己登錄與 COM 環境中,通常是啟動 VSIP 計畫,呼叫 DLL 的 managed 程式碼regpkg.exe。 撰寫 COM 環境的登錄機碼的實際程序會自動處理。
主要類別的方法會以標記ComRegisterFunctionAttribute,表示該方法當 com 註冊的 DLL 時呼叫 這種註冊方法,通常稱為RegisterClass,會執行的工作,以 Visual Studio 登錄的 DLL。 相關UnregisterClass (帶有ComUnregisterFunctionAttribute),復原所造成的影響RegisterClass時解除安裝的 DLL。
相同的登錄項目有針對為 EE 撰寫 unmanaged 程式碼路徑。 唯一的差別在於沒有任何的 helper 函式類似SetEEMetric為您執行工作。 這項註冊/取消註冊程序的範例如下所示:
範例
這個函式會顯示 managed 程式碼為 EE 會註冊並移除本身註冊與 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);
}
}
}
}
未受管理的程式碼運算式評估工具
EE DLL 會實作DllRegisterServer登錄 COM 環境以及 Visual Studio 的函式。
注意事項 |
---|
MyCEE 的程式碼範例登錄程式碼可以在檔案 dllentry.cpp,位於 EnVSDK\MyCPkgs\MyCEE VSIP 安裝中找到。 |
DLL 伺服器處理序
當登錄的 EE DLL 伺服器:
註冊其類別工廠CLSID根據一般的 COM 慣例。
Helper 函式會呼叫SetEEMetric用來登錄 Visual Studio 下表所示的 EE 度量資訊。 此函式SetEEMetric下, 面指定的度量資訊是 dbgmetric.lib 程式庫的一部分。 如需詳細資訊,請參閱SDK 的協助程式進行偵錯。
公制
描述
metricCLSID
CLSIDEE 類別工廠
metricName
可顯示的字串為 EE 的名稱
metricLanguage
名稱為 EE 語言設計用來評估
metricEngine
GUIDs 與此 EE 搭配使用的偵錯引擎 (DE)
注意事項 metricLanguageGUID地識別的名稱,但它的語言版本是guidLang引數為SetEEMetric所選取的語言。當編譯器產生偵錯資訊檔時,它應該撰寫適當的guidLang好讓 DE 知道要使用哪一個 EE。DE 通常會符號提供者要求此語言的GUID,均會儲存在 [偵錯資訊檔。
藉由建立 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\ 機碼會註冊與 Visual StudioX.Y,其中 X.Y 是用來登錄 Visual Studio 的版本。
範例
這個函式會顯示如何 unmanaged 程式碼 (c + +) 卻會註冊並移除本身註冊與 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;
}