.NET Framework を扱うクラス (ClrHelper)

(2007.06.06)
#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;
    }
};
一覧に戻る
© 2003 WAC.com All Right Reserved.