중요합니다
Visual Studio 2015에서는 식 계산기를 구현하는 이러한 방법이 더 이상 사용되지 않습니다. CLR 식 계산기 구현에 대한 자세한 내용은 CLR 식 계산기 및 관리 식 계산기 샘플을 참조하세요.
EE(식 계산기)는 Windows COM 환경과 Visual Studio를 모두 사용하여 클래스 팩터리로 등록해야 합니다. EE는 EE를 인스턴스화하는 엔터티에 따라 디버그 엔진(DE) 주소 공간 또는 Visual Studio 주소 공간에 삽입되도록 DLL로 설정됩니다.
관리 코드 식 평가기
관리 코드 EE는 COM 환경에 자신을 등록하는 DLL인 클래스 라이브러리로 구현되며, 일반적으로regpkg.exeVSIP 프로그램에 대한 호출로 시작 됩니다. COM 환경에 대한 레지스트리 키를 작성하는 실제 프로세스는 자동으로 처리됩니다.
주 클래스의 메서드는 DLL이 COM에 등록될 때 호출해야 함을 나타내는 ComRegisterFunctionAttribute로 표시됩니다. 자주 호출 RegisterClass되는 이 등록 메서드는 Visual Studio에 DLL을 등록하는 작업을 수행합니다. 해당 UnregisterClass (ComUnregisterFunctionAttribute로 표시된)는 DLL이 제거될 때 RegisterClass의 효과를 되돌립니다.
관리되지 않는 코드로 작성된 EE와 동일한 레지스트리 항목이 생성됩니다. 유일한 차이점은 작업을 수행하는 것과 같은 SetEEMetric 도우미 함수가 없다는 것입니다. 다음은 등록 및 등록 취소 프로세스의 예입니다.
Example
다음 함수는 관리 코드 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에도 자체 등록합니다.
비고
파일 dllentry.cpp EnVSDK\MyCPkgs\MyCEE 아래의 VSIP 설치에 있는 MyCEE 코드 샘플 레지스트리 코드를 찾을 수 있습니다.
DLL 서버 프로세스
EE를 등록할 때 DLL 서버:
일반적인 COM 규칙에 따라 클래스 팩터
CLSID리를 등록합니다.도우미 함수
SetEEMetric를 호출하여 다음 표에 표시된 EE 메트릭을 Visual Studio에 등록합니다. 다음과 같이 지정된 함수SetEEMetric및 메트릭은 dbgmetric.lib 라이브러리의 일부입니다. 자세한 내용은 디버깅에 대한 SDK 도우미를 참조하세요.Metric Description metricCLSIDEE 클래스 팩터리의 CLSIDmetricName표시 가능한 문자열로 EE의 이름 metricLanguageEE가 평가하도록 설계된 언어의 이름입니다. metricEngineGUID이 EE와 함께 작동하는 디버그 엔진(DE)들비고
metricLanguage``GUID는 언어의 이름을 식별하지만, 언어를 선택하는 것은SetEEMetric에 대한guidLang인수입니다. 컴파일러가 디버그 정보 파일을 생성할 때 DE에서 사용할 EE를 알 수 있도록 적절한guidLang파일을 작성해야 합니다. DE는 일반적으로 디버그 정보 파일에 저장된 이 언어GUID에 대해 기호 공급자에게 요청합니다.HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\X.Y에서 키를 만들어 Visual Studio에 등록합니다. 여기서 X.Y 는 등록할 Visual Studio 버전입니다.
Example
다음 함수는 관리되지 않는 코드(C++) EE가 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;
}