いつも拝見させて頂いています。
Windowsでアドミン権限を持たないユーザがインストール作業を行える様にする処理を
作っています。
・流れ
1) Aプログラムが起動
2) Aプログラム内でCreateProcess関数を動かす
3) ※Setup.exeを起動
2)の処理で、CreateProcessを起動すると本来開かれるはずの
”別のユーザとしてプログラムをインストール”というダイアログが表示されません。
これを表示させるように設定するにはどうしたら良いのでしょうか。
※Setup.exeはInstallSieldで作ってある事を想定しています。
とりあえず以下3点は確認したほうがよろしいかと。
1.Aプログラムは本当に起動されているか?
2.CreateProcess の処理は本当に実行されているか?
3.CreateProcess が実行されているとしてエラーは発生していないか?
これらが不明なままでは回答できる人もなかなかいないと思われますんで。
>1.Aプログラムは本当に起動されているか?
起動しています。
>2.CreateProcess の処理は本当に実行されているか?
Setup.exeがプロセスで起動されるのを確認しました。
>3.CreateProcess が実行されているとしてエラーは発生していないか?
戻り値は正常な値(!=0)が帰って来ています。
以上確認しました。
CreateProcess が正常に実行されているならば、起動される側の
Setup.exe も一応疑うとします。
Setup.exe ではなく、ほかのプログラムを CreateProcess で
試しに起動した場合はどうでしょう?
(notepad.exe 等起動が確認されているもの)
あと、 Setup.exe を CreateProcess ではなくエクスプローラ等から
起動した場合はどうなんでしょう?
これで起動していなかったら明らかに Setup.exe の問題とは
思いますが。
もう一つ付け加えるなら、CreateProcess 近辺のソースを
ここに載せれば添削してくれる人がいるかもしれません。
とりあえず色々試して問題の切り分けを行わないと。
「別のユーザとしてプログラムをインストール」というのは
OSの機能ではなくエクスプローラの機能のような気がします。
例えば、DOSプロンプトからSETUP.EXEを起動しても、ダイアログは出ません。
ひょっとすると、ShellExecute(Ex)を使ってシェル経由でファイルを開くと
ダイアログが出るかもしれません。
これが駄目なら、独自にログイン・ダイアログを作って
CreateProcessAsUserを使うとか…。
ご返事ありがとうございます
>あと、 Setup.exe を CreateProcess ではなくエクスプローラ等から
起動した場合はどうなんでしょう?
制限ユーザの場合、別のユーザとしてプログラムをインストールのダイアログが出て
ユーザ名、パスワード、ドメインを入力するように施されます。
>CreateProcess 近辺のソースを
と、言ってもこれぐらいですが(汗
###############################################
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof( STARTUPINFO ));
si.cb = sizeof( STARTUPINFO );
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;
::CreateProcess( NULL, setup.exe, NULL, NULL, FALSE, 0, NULL, NULL, &si,
&pi );
###############################################
>例えば、DOSプロンプトからSETUP.EXEを起動しても、ダイアログは出ません。
色々試した結果、DOSプロンプトからやCreateProcessで起動した場合は
ダイアログが出ない事が分かりました。
「スタート」から、ファイル名を指定して実行を行うと出るのが謎ですが。
>ShellExecute(Ex)を使ってシェル経由でファイルを開くと
もしかしたら出るかも知れません。試してみます。
>これが駄目なら、独自にログイン・ダイアログを作って
CreateProcessAsUserを使うとか…。
それが出来たら楽だったのですが、LogonUser関数でトークンを取得できない環境に
ある為、使えない羽目に陥っていました。
今あきらめかけてCreateProcessWithLogonW関数を使って出来ないか調査をしている
所です。
シェルは盲点でした。色々試してみます。
--Source--
BOOL xp_2k(LPCSTR sUser, LPCSTR sPassword, LPCSTR sDomain, LPCSTR sCommand)
{
WCHAR cmd[Buffers];
WCHAR user[Buffers];
WCHAR domain[Buffers];
WCHAR pass[Buffers];
STARTUPINFOW si;
PROCESS_INFORMATION pi;
HMODULE hADVAPI32;
hADVAPI32 = LoadLibrary( ADVAPI32.DLL );
if( hADVAPI32 < (HINSTANCE)HINSTANCE_ERROR)
return FALSE;
CreateProcessWithLogonWD = (CREATEPROCESSWITHLOGONWD)
GetProcAddress(
hADVAPI32, CreateProcessWithLogonW );
if( CreateProcessWithLogonWD == NULL )
return FALSE;
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sUser, -1, user, sizeof
user );
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sDomain, -1, domain,
sizeof domain );
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sCommand, -1, cmd,
sizeof cmd );
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sPassword, -1, pass,
sizeof pass );
si.cb = sizeof( STARTUPINFOW );
si.lpReserved = NULL;
si.lpDesktop = NULL;
si.lpTitle = NULL;
si.dwFlags = 0;
si.cbReserved2 = 0;
si.lpReserved2 = NULL;
if( CreateProcessWithLogonWD( user, domain, pass, LOGON_WITH_PROFILE,
NULL, cmd,
CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE |
CREATE_NEW_PROCESS_GROUP | CREATE_SEPARATE_WOW_VDM,
NULL, NULL, &si, &pi ) == FALSE ){
// RCELog::Printf( 2, RCECSu, 実行エラー );
#ifdef _DEBUG
OutputDebugString(実行エラー\n);
#endif // _DEBUG
return FALSE;
}
return TRUE;
}
ShellExecuteで動かした場合にダイアログが出ました。
問題がほぼ解決しました。
ありがとうございます(w