別アカウントでコンソールアプリを起動して標準出力を取得するには? – プログラミング – Home

別アカウントでコンソールアプリを起動し...
 
通知
すべてクリア

[解決済] 別アカウントでコンソールアプリを起動して標準出力を取得するには?


AGM-65
 AGM-65
(@AGM-65)
ゲスト
結合: 15年前
投稿: 4
Topic starter  

自プロセスから子プロセス(コンソールアプリ)を別アカウントで起動し、
名前なしパイプを使って子プロセスの標準出力を随時取得するプログラムを
作成していますが、CreateProcessWithLogonWで失敗してしまいます。
直後のGetLastErrorでは6→The handle is invalid.(ハンドルが無効です。)と
返ってきます。
Web検索やMSDNを読んだり、自分なりに色々調べて試してみたのですが、
原因・解決策を見つけられませんでした。

通常のCreateProcessですと問題なく動作する点、pipeを使用せずに
 //StartUpInfo設定
 ZeroMemory(&siStartInfo,sizeof(STARTUPINFO));
 siStartInfo.cb = sizeof(STARTUPINFO);
 siStartInfo.dwYCountChars = 50;
 siStartInfo.lpTitle = NULL;
として、CreateProcessWithLogonWで起動する分にも正常に動作することから、
pipeの生成方法、もしくはそもそも別アカウントの標準出力をpipeで読むことが
できない?とも思っております。
ソースコードの間違い、など、アドバイス、解決策、参考意見、何でも構いませんので、
どなたかお知恵をお貸しいただけないでしょうか。

■環境
Windows XP Pro(SP2)
Visual C++8(Visual Studio 2005)
プログラムを動作させているアカウント:domain参加ユーザー
起動したいプロセスのアカウント:コンピューター上のユーザー(Admin権限)

■ソースコード(エラー処理は省略してます)

HANDLE hChildStdOutR;
HANDLE hChildStdOutW;
HANDLE hChildStdOutRDup;
HANDLE hSaveStdOut;

//SECURITY_ATTRIBUTEの設定
SECURITY_ATTRIBUTES SecAtt;
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;

SecAtt.nLength = sizeof(SECURITY_ATTRIBUTES);
SecAtt.bInheritHandle = TRUE;
SecAtt.lpSecurityDescriptor = NULL;

hSaveStdOut = GetStdHandle(STD_OUTPUT_HANDLE);

//標準出力pipeの生成
CreatePipe(&hChildStdOutR, &hChildStdOutW, &SecAtt, 0);

//標準出力へのリダイレクション
SetStdHandle(STD_OUTPUT_HANDLE, hChildStdOutW);

//読み取りハンドルの複製
DuplicateHandle(GetCurrentProcess(),
hChildStdOutR,
GetCurrentProcess(),
&hChildStdOutRDup ,
0,
FALSE,DUPLICATE_SAME_ACCESS);

CloseHandle(hChildStdOutR);

// PROCESS_INFORMATION構造体初期化
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );

// STARTUPINFO 構造体設定
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW ;
siStartInfo.hStdOutput = hChildStdOutW;
siStartInfo.hStdError = hChildStdOutW;
siStartInfo.wShowWindow = SW_HIDE;

//コンピュータ名取得
wchar_t wzComputerName[MAX_PATH];
GetComputerName(wzComputerName,&dSize);

CreateProcessWithLogonW(
Lhoge, // ユーザーの名前
wzComputerName, // ユーザーのドメイン(ローカルなのでコンピュータ名)
Lpassword, // ユーザーのパスワード
LOGON_WITH_PROFILE, // ログオン オプション
LC:\ADC\ConsoleApp.exe, // 実行可能モジュール名
LConsoleApp -f hoge.txt", // コマンドライン文字列
CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE |
CREATE_NEW_PROCESS_GROUP , // 作成フラグ
NULL, // 新しい環境ブロック
LC:\HogeApp, // カレントディレクトリの名前
&siStartInfo,
&piProcInfo
);

DWORD dRet;
dRet = GetLastError();

・・・・


引用未解決
トピックタグ
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

ping.exeで試してみましたが普通に取れました。
STARTUPINFOW の hStdInput が設定されていないことが原因?かも。


返信引用
AGM-65
 AGM-65
(@AGM-65)
ゲスト
結合: 15年前
投稿: 4
Topic starter  

subaruさん、ありがとうございます。

siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
としてみたのですが、結果は同じでした。
恐らく指定するものが間違っているのでしょうが、
subaruさんは何を設定されたのでしょうか?
標準入力用のpipeを別に作って指定するのでしょうか。


返信引用
AGM-65
 AGM-65
(@AGM-65)
ゲスト
結合: 15年前
投稿: 4
Topic starter  

subaruさんのアドバイスをきっかけに自己解決しました。
どうもお騒がせしました。


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

>siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
>としてみたのですが、結果は同じでした。
ありゃ、起動すらできませんでしたか。。。
他に原因があるのかな?

>標準入力用のpipeを別に作って指定するのでしょうか。
hStdInput=NULL → ERROR_INVALID_HANDLE
hStdInput=GetStdHandle(STD_INPUT_HANDLE) → OK
標準入力用のpipeを別に作成 → OK
でした。
ちなみにXP SP3です。


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

入れ違いでしたね(^^ゞ
解決してなによりでした。


返信引用
AGM-65
 AGM-65
(@AGM-65)
ゲスト
結合: 15年前
投稿: 4
Topic starter  

ホントに入れ違いだったんですね・・・
まさにsubaruさんの指摘通りです。

hStdInputに標準入力用のpipeを別に作成したらOKでした。

自プロセス(親)がダイアログベース故に標準入力がないので
GetStdHandle(STD_INPUT_HANDLE)で取得した0x00000000を
セットするのが不適切だったのかなと・・・
(試しにコンソールアプリで親プロセスを作ってみて試したところ、
subaruさんと同様の結果になりました。)

でもsubaruさんもダイアログベースでOKだったのなら不思議ですね。


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

ご察しの通りコンソールアプリでしか試してませんでした。
WinMain/wWinMainがエントリーポイントの時は標準入力/標準出力がない
ことをすっかり忘れていました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました