#pragma once
// WAC.com Class Liblary for Visual C++
// Copyright (C) WAC.com Inc. All rights reserved.
//
// This file is a part of the WAC.com Class Liblary.
// The use and distribution terms for this software are covered by the
// Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
// any other, from this software.
// '04.12.25 : インストール確認方法を変更 (sha)
// '05.08.10 : コードの整備 (sha)
// '07.05.08 : コードの整備 (sha)
// '07.06.06 : コードの整備 (sha)
#include <mscoree.h>
#pragma comment(lib, "mscoree.lib")
#pragma warning(push)
#pragma warning(disable: 4192)
#pragma warning(disable: 4278)
#pragma warning(disable: 4279)
#import <mscorlib.tlb> // CLR
#pragma warning(pop)
_COM_SMARTPTR_TYPEDEF(ICorRuntimeHost, __uuidof(ICorRuntimeHost));
_COM_SMARTPTR_TYPEDEF(ICorConfiguration, __uuidof(ICorConfiguration));
#include <shlwapi.h> // SHLWAPI
#pragma comment(lib, "shlwapi.lib")
#include "RegHelper.h"
// CLRのバージョン文字列
#define CLR_VERSION10 _T("v1.0.3705")
#define CLR_VERSION11 _T("v1.1.4322")
#define CLR_VERSION20 _T("v2.0.50215")
////////////////////////////////////////////////////////////////////////////////
// CClrHelper
class CClrHelper
{
protected:
typedef CClrHelper thisClass;
protected:
CClrHelper(); // 実装しない。。
virtual ~CClrHelper();
public:
/*
// CLRがインストールされているか?
// この方法では、CLRのバージョンが指定できない
static bool IsRuntimeInstalled()
{
CString strFileName = _T("mscoree.dll");
HMODULE hModule = ::LoadLibrary(strFileName);
if (hModule == NULL)
{
return false;
}
::FreeLibrary(hModule);
return true;
}
*/
#if 0 // Del sha '04.12.25
// CLRがインストールされているか?
static bool IsRuntimeInstalled(LPCTSTR szVersion = CLR_VERSION11)
{
CString strClrRootDirectory = CClrHelper::GetClrInstallRootDirectory();
if (strClrRootDirectory.IsEmpty())
{
return false;
}
CString strClrSystemDirectory = strClrRootDirectory + CString(szVersion) + _T("\\");
CString strFileName = strClrSystemDirectory + _T("Mscorcfg.dll");
HMODULE hModule = ::LoadLibrary(strFileName);
if (hModule == NULL)
{
return false;
}
::FreeLibrary(hModule);
return true;
}
#else // Add sha '04.12.25
// DotNetFxSetupHelper.hより、コピー
// CLRがインストールされているか?
static bool IsDotNetFxInstalled(LPCTSTR szVersion = CLR_VERSION11)
{
CString strSubKey;
strSubKey.Format(_T("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\%s"), szVersion);
DWORD dwInstall = CRegHelper::SHRegGetInt(
HKEY_LOCAL_MACHINE,
strSubKey,
_T("Install"));
if (dwInstall == 0)
{
return false;
}
return true;
}
#endif
public:
#if 0
// インストール ルート フォルダの取得
static CString GetClrInstallRootDirectory()
{
// return CShlwapiHelper::GetWindowsDirectory() + _T("Microsoft.NET\\Framework\\");
return CClrHelper::GetWindowsDirectory() + _T("Microsoft.NET\\Framework\\");
}
#else
// インストール ルート フォルダの取得
static CString GetClrInstallRootDirectory()
{
CString strValue = CRegHelper::SHRegGetString(
HKEY_LOCAL_MACHINE,
_T("SOFTWARE\\Microsoft\\.NETFramework"),
_T("InstallRoot"));
if (strValue.IsEmpty())
{
return _T("");
}
strValue = CClrHelper::PathAddBackslash(strValue);
return strValue;
}
#endif
public:
#if 1
// http://blogs.msdn.com/junfeng/archive/2005/07/07/436755.aspx
// http://www.codeproject.com/dotnet/DetectDotNet.asp?df=100&forumid=199130&exp=0&select=1164636
// CLRの列挙
// ディレクトリの列挙版
static HRESULT EnumClrVersion(std::vector<CString>& strClrVersions)
{
strClrVersions.clear();
CString strClrRootDirectory = CClrHelper::GetClrInstallRootDirectory();
if (strClrRootDirectory.IsEmpty())
{
return S_FALSE;
}
CString strFindFileName = strClrRootDirectory + _T("*.*");
WIN32_FIND_DATA wfd;
HANDLE h = ::FindFirstFile(strFindFileName, &wfd);
if (h == INVALID_HANDLE_VALUE)
{
return S_FALSE;
}
do
{
if (_tcscmp(wfd.cFileName, _T(".")) != 0 && _tcscmp(wfd.cFileName, _T("..")) != 0)
{
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
CString strClrVersion = wfd.cFileName;
bool bIsInstalled = CClrHelper::IsDotNetFxInstalled(strClrVersion);
if (!bIsInstalled)
{
continue;
}
strClrVersions.push_back(wfd.cFileName);
}
}
}
while (::FindNextFile(h, &wfd));
::FindClose(h);
return (strClrVersions.size() > 0) ? S_OK : S_FALSE;
}
#else
// CLRの列挙
// レジストリの列挙版
// → 1.0 が列挙されない。。
static HRESULT EnumClrVersion(std::vector<CString>& strClrVersions)
{
HRESULT hr = S_OK;
hr = CRegHelper::RegEnumKey(
HKEY_LOCAL_MACHINE,
// _T("SOFTWARE\\Microsoft\\.NETFramework\\PendingUpdates"),
_T("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP"),
strClrVersions);
if (FAILED(hr))
{
return S_FALSE;
}
return (strClrVersions.size() > 0) ? S_OK : S_FALSE;
}
#endif
public:
// 未検証
// CLRホストの取得
static ICorRuntimeHostPtr BindToCurrentRuntime(LPCTSTR szFileName)
{
USES_CONVERSION;
HRESULT hr = S_OK;
ICorRuntimeHostPtr spCorRuntimeHost;
hr = ::CorBindToCurrentRuntime(
T2W((LPTSTR)szFileName),
CLSID_CorRuntimeHost,
__uuidof(ICorRuntimeHost),
(void**)&spCorRuntimeHost);
if (FAILED(hr))
{
return NULL;
}
return spCorRuntimeHost;
}
// CLRホストの取得
static ICorRuntimeHostPtr BindToRuntimeEx(
LPCTSTR szVersion = CLR_VERSION11,
LPCTSTR szBuildFlavor = _T("wks"),
DWORD dwFlags = STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST | STARTUP_CONCURRENT_GC)
{
USES_CONVERSION;
HRESULT hr = S_OK;
ICorRuntimeHostPtr spCorRuntimeHost;
hr = ::CorBindToRuntimeEx(
T2W((LPTSTR)szVersion),
T2W((LPTSTR)szBuildFlavor),
dwFlags,
CLSID_CorRuntimeHost,
__uuidof(ICorRuntimeHost),
(void**)&spCorRuntimeHost);
if (FAILED(hr))
{
return NULL;
}
return spCorRuntimeHost;
}
public:
// CLRのバージョンの取得
static CString GetClrVersion()
{
USES_CONVERSION;
HRESULT hr = S_OK;
WCHAR wszResult[1024] = { 0 };
DWORD dwlength = 0;
hr = ::GetCORVersion(wszResult, sizeof(wszResult), &dwlength);
if (FAILED(hr))
{
return _T("");
}
return W2T(wszResult);
}
// CLRのディレクトリの取得
static CString GetClrSystemDirectory()
{
USES_CONVERSION;
HRESULT hr = S_OK;
WCHAR wszResult[MAX_PATH] = { 0 };
DWORD dwlength = 0;
hr = ::GetCORSystemDirectory(wszResult, sizeof(wszResult), &dwlength);
if (FAILED(hr))
{
return _T("");
}
// ::PathAddBackslashW(wszResult); // SHLWAPI 4.71
return W2T(wszResult);
}
protected:
/*
// ShlwapiHelper.hからコピー
static CString GetWindowsDirectory()
{
TCHAR szResult[MAX_PATH] = { 0 };
UINT nr = ::GetWindowsDirectory(szResult, _countof(szResult));
if (nr == 0)
{
return _T("");
}
::PathAddBackslash(szResult); // SHLWAPI 4.71
return szResult;
}
*/
// ShlwapiHelper.hからコピー
// バックスラッシュを付加する
static CString PathAddBackslash(CString strPath)
{
TCHAR szPath[_MAX_PATH] = { 0 };
#ifdef _SECURE_ATL
_tcscpy_s(szPath, strPath);
#else
_tcscpy(szPath, strPath);
#endif
::PathAddBackslash(szPath); // SHLWAPI 4.71
return szPath;
}
};