(C++)別ユーザでプロセスを起動する
Windows API を使って別のユーザでプロセスを起動する方法です。
(.Net を使えば、ProcessStartInfo.UserName や ProcessStartInfo.Password 等で簡単にできるのかもしれませんが、.Net Framework が入ってない環境を考慮して C++ と Windows API で作成しました。またコマンドプロンプトで、 RUNAS を使うとできるのですが、パスワードを入力しないといけないので自作することとしました。)
別ユーザでプロセスを起動する Windows API としては、CreateProcessAsUserやCreateProcessWithLogonW、CreateProcessWithTokenW(Vista以降)などがあるようですが、今回は一番簡単そうな、CreateProcessWithLogonW 関数を使ってみました。
下記のような感じで可能です。administrator@hogedomain.local でWSH(VBScript)を実行するコードです。
#include "stdafx.h"#include
STARTUPINFO sinfo;
PROCESS_INFORMATION pinfo;
ZeroMemory( &sinfo, sizeof( STARTUPINFO ) );
ZeroMemory( &pinfo, sizeof( PROCESS_INFORMATION ) );
sinfo.cb = sizeof( STARTUPINFO );
//別ユーザでプロセス起動
if( ! CreateProcessWithLogonW( _T("administrator"), //ユーザ名
_T("hogedomain.local"), //ドメイン名
_T("passwd"), //パスワード
0, //ログオン オプション LOGON_NETCREDENTIALS_ONLYを指定すると呼び出し元ユーザプロセスで動いてしまいました
NULL, //実行可能モジュール名
_T("cscript.exe \"d:\\a.vbs\""), //コマンドライン文字列
CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP , //作成フラグ
NULL, // 新しい環境ブロック
NULL, // カレントディレクトリの名前
&sinfo,
&pinfo)){
if (GetLastError() == ERROR_ACCESS_DENIED){
MessageBox(NULL, TEXT("アクセスが拒否されました。"), NULL, MB_ICONWARNING);
}
else
{
MessageBox(NULL, TEXT("プロセスの作成に失敗しました。"), NULL, MB_ICONWARNING);
}
return 0;
}
CloseHandle(pinfo.hThread);
CloseHandle(pinfo.hProcess);
上記は cscript でWSHを実行するため、コマンドライン文字列に定義しましたが、一般のexeを実行する場合は第5引数にexeのパスを指定するようです。
メモ帳を立ち上げる場合はこうなります。
CreateProcessWithLogonW( _T("administrator"), //ユーザ名_T("hogedomain.local"), //ドメイン名
_T("passwd"), //パスワード
0, //ログオン オプション LOGON_NETCREDENTIALS_ONLYを指定すると呼び出し元ユーザプロセスで動いてしまいました
_T("notepad.exe"), //実行可能モジュール名
NULL, //コマンドライン文字列
CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP , //作成フラグ
NULL, // 新しい環境ブロック
NULL, // カレントディレクトリの名前
&sinfo,
&pinfo)
参考:
CreateProcessWithLogonW or CreateProcessAsUser - .NET Framework .NetのProcessStartInfo.UserName を使って、プロセスを起動した場合、CreateProcessWithLogonW が呼ばれるみたいです。
別ユーザーのプロセス 非常に参考なりました。