3流プログラマのメモ書き

元開発職→現社内SEの三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。(jehupc.exblog.jpから移転中)

(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 が呼ばれるみたいです。

別ユーザーのプロセス 非常に参考なりました。

MSDN:CreateProcessWithLogonW

MSDN:別アカウントでプロセスを起動する方法