#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.
// '06.03.22 : UNICODEビルドに対応 (sha)
// '06.09.29 : APIに渡すTCHARのバッファサイズ修正 (his)
// '07.03.09 : _countofを使うように修正 (sha)
// '07.04.16 : コードの整備 (sha)
#include "Module.h"
#if _MSC_VER < 1400
#if !defined(_countof)
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
#endif
#endif
/////////////////////////////////////////////////////////////////////////////
// CRundll32Helper
class CRundll32Helper
{
protected:
typedef CRundll32Helper thisClass;
protected:
CRundll32Helper(); // 実装しない
virtual ~CRundll32Helper();
public:
static bool IsSupported(LPCTSTR szFileName, LPCTSTR szEntryName)
{
CModule module;
HINSTANCE hInst = module.LoadLibrary(szFileName);
if (hInst == NULL)
{
return false;
}
typedef void CALLBACK FUNC_EntryPoint(HWND hwnd, HINSTANCE hinst, LPTSTR lpCmdLine, int nCmdShow);
FUNC_EntryPoint* func = (FUNC_EntryPoint*)module.GetProcAddress(szEntryName);
if (func == NULL)
{
return false;
}
return true;
}
static HRESULT Invoke(HWND hWnd, HINSTANCE hInst, LPCTSTR szFileName, LPCTSTR szEntryName, LPCTSTR szCmdLine = NULL, int nCmdShow = SW_SHOWNORMAL)
{
CModule module;
HINSTANCE hInst2 = module.LoadLibrary(szFileName);
if (hInst2 == NULL)
{
return E_NOTIMPL;
}
typedef void CALLBACK FUNC_EntryPoint(HWND hwnd, HINSTANCE hinst, LPTSTR lpCmdLine, int nCmdShow);
FUNC_EntryPoint* func = (FUNC_EntryPoint*)module.GetProcAddress(szEntryName);
if (func == NULL)
{
return E_NOTIMPL;
}
func(hWnd, hInst, (LPTSTR)szCmdLine, SW_SHOWNORMAL);
return S_OK;
}
static HRESULT InvokeProcess(/*HWND hWnd, HINSTANCE hInst,*/ LPCTSTR szFileName, LPCTSTR szEntryName, LPCTSTR szCmdLine = NULL, int nCmdShow = SW_SHOWNORMAL)
{
HRESULT hr = S_OK;
CString strCommand = _T("Rundll32.exe ") + thisClass::GetShortPathName(szFileName) + _T(",") + CString(szEntryName);
DWORD dwExitProcessCode = 0;
hr = thisClass::CreateProcessWaitForExit(strCommand, dwExitProcessCode);
if (FAILED(hr))
{
return hr;
}
return hr;
}
public:
// http://hp.vector.co.jp/authors/VA022217/tips/hsp/rundll.html に色々なサンプルが載っている
// プリンタの追加ウィザード
static HRESULT ShowAddPrinterWizard(HWND hWnd, HINSTANCE hInst)
{
HRESULT hr = S_OK;
hr = thisClass::Invoke(hWnd, hInst, _T("shell32.dll"), _T("SHHelpShortcuts_RunDLL"), _T("AddPrinter"));
if (FAILED(hr))
{
// エラー
return hr;
}
return hr;
}
protected:
// FileHelper.hから、コピー
// Win95, WinNT3.5 or lator
static CString GetShortPathName(LPCTSTR szLongPath)
{
TCHAR szShortPath[_MAX_PATH] = { 0 };
DWORD dwResult = ::GetShortPathName(szLongPath, szShortPath, _countof(szShortPath));
if (dwResult == 0)
{
return _T("");
}
return szShortPath;
}
static HRESULT CreateProcessWaitForExit(LPCTSTR szFileName, DWORD& dwExitProcessCode)
{
dwExitProcessCode = 0;
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi = { 0 };
BOOL br = ::CreateProcess((LPCTSTR)NULL, (LPTSTR)szFileName, NULL, NULL, TRUE, 0, NULL,NULL, &si, &pi);
if (br == 0)
{
DWORD dwError = ::GetLastError();
return HRESULT_FROM_WIN32(dwError);
}
// スレッドのハンドルは使わないのですぐ破棄
::CloseHandle(pi.hThread);
// プロセスが終了するまでまつ
::WaitForSingleObject(pi.hProcess, INFINITE);
br = ::GetExitCodeProcess(pi.hProcess, &dwExitProcessCode);
if (br == FALSE)
{
// 無視する。。
}
// もうプロセスのハンドルは使わないので破棄
::CloseHandle(pi.hProcess);
return S_OK;
}
};