2011年2月13日 星期日

下面是我花了一天的研究成果!

下面這段程式是用 C++ 啟動 .Net Runtime 的範例,利用這範例可以寫出偵測戶端有沒有安裝 .Net Framework 的前導程式。我知道很難理解,由其是沒寫過 C++ 的人...


 參考來源:http://msdn.microsoft.com/zh-tw/library/dd380851.aspx

#include "stdafx.h"

#include <iostream>
#include <Metahost.h>
//#include <mscoree.h>
#include <CorError.h>

#pragma comment(lib, "mscoree.lib")

// LPCWSTR 不可變的寬字元。
// LPWSTR 可變的寬字元,要用 malloc 初始化。

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
ICLRMetaHost *pMetaHost = NULL;
//ICLRMetaHostPolicy *pMetaHostPolicy = NULL;
//ICLRDebugging *pCLRDebugging   = NULL;
HRESULT hr;

hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost,
(LPVOID*)&pMetaHost);
//hr = CLRCreateInstance (CLSID_CLRMetaHostPolicy, IID_ICLRMetaHostPolicy,
// (LPVOID*)&pMetaHostPolicy);
//hr = CLRCreateInstance (CLSID_CLRDebugging, IID_ICLRDebugging,
// (LPVOID*)&pCLRDebugging);

ICLRRuntimeInfo *clr = NULL;
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo,(LPVOID *)&clr);
ICLRRuntimeHost *runtime= NULL;

hr = clr->GetInterface(CLSID_CLRRuntimeHost , IID_ICLRRuntimeHost, (LPVOID*)&runtime);

hr = runtime->Start();

//執行 .Net Manage 程式。
//DWORD *retval = 0;
//hr = runtime->ExecuteInDefaultAppDomain(L"C:\\Users\\Yaoming\\Documents\\visual studio 2010\\Projects\\ClrApp\\ClrApp\\bin\\Debug\\ClrApp.dll"
// ,L"ClrApp.Program",L"AppMain",L"",retval);

//取得已安裝的 .Net Runtime 版本字串。
IEnumUnknown *setups = NULL;
hr = pMetaHost->EnumerateInstalledRuntimes(&setups);
ICLRRuntimeInfo *rt; 
ULONG actual;
while((hr = setups->Next(1, (IUnknown**)&rt, &actual)) == S_OK)  
{
DWORD buffer = 20;
LPWSTR ver = (LPWSTR)malloc(buffer * sizeof(LPWSTR));
hr = rt->GetVersionString(ver,&buffer);

if(hr == S_OK)
cout << ver << endl;
else
cout << "Get version fail." << endl;

hr = pMetaHost->GetRuntime(ver, IID_ICLRRuntimeInfo,(LPVOID *)&clr);

if(hr == S_OK)
cout << ver << endl;
else
cout << "Get runtime fail." << endl;
}

if(hr == S_OK)
cout << "S_OK" << endl;
else if (hr == HOST_E_CLRNOTAVAILABLE)
cout << "Clr Not available" << endl;
else if (hr == HOST_E_TIMEOUT)
cout << "Time out " << endl;
else if(hr == HOST_E_NOT_OWNER)
cout << "Not owner" << endl;
else if(hr == HOST_E_ABANDONED)
cout << "abandoned" << endl;
else
cout << "Fail" << endl;

system("pause");

return 0;
}