こんにちは。
今、MFCで簡単なプログラムを作っています。
その中で、DOSコマンド(正確には「net」コマンド)を実行させています。
現在、このコマンドを
system("net xxxxxx xxxx xxxx");
といった形で実行しているので、DOS窓が表示されてしまいます。
これを表示させずに実行させることはできないでしょうか?
方法があるようでしたら、教えてください。
宜しくお願いします。
CreateProcessでフラグを設定して起動させればできるのでは?
APIで自分で実装,という手段もあります。
どらです。
CreateProcessに関してですが、VCのヘルプ(MSDNライブラリ)を見ても、フラグをどの様にすればバックグラウンドで実行してくれるのかわからないのですが・・・
よろしければ教えていただけないでしょうか?
また、過去ログから、
コマンドインタプリタごと起動してやればCreateProcessで実行できますよ。
とYuOさんが発言しているのですが、これはどういうことなのでしょうか?
何も知らなくて申し訳ないです。
実際にやりたいことは、ダイアログベースプログラム中で
net user "user_name" "password" /domain >"出力ファイル名"
と言うコマンドを、DOS窓を表示させずに実行させたいんです・・・。
> CreateProcessに関してですが、VCのヘルプ(MSDNライブラリ)を見ても、
> フラグをどの様にすればバックグラウンドで実行してくれるのか
> わからないのですが・・・
MSDN をよっく見てください。
ほら、こんな一文が。
> CREATE_NO_WINDOW
> Windows NT/2000:このフラグは、コンソールアプリケーションを起動する
> 場合にのみ有効です。このフラグを指定すると、コンソールウィンドウ
> なしでアプリケーションを実行します。
> また、過去ログから、
> コマンドインタプリタごと起動してやればCreateProcessで実行できますよ。
> とYuOさんが発言しているのですが、これはどういうことなのでしょうか?
その発言の前後を知らないので正確なところはわかりませんが、
例えば dir など、独立した exe でない DOS コマンドは CreateProcess
では実行できませんので、そういう場合はコマンドインタプリタ(cmd.exe)
を CreateProcess してやればいいということだと思います。
net コマンドの場合は NET.EXE というファイルがあるので、インタプリタを
介する必要はないかと思われますが。
> net user "user_name" "password" /domain >"出力ファイル名"
出力ファイル名の部分はコマンドラインに渡してもできない気がします
ので、別途リダイレクトしてやる必要があると思います。
#「べっとりダイレクト」って変換された。ヤだなぁ…
え〜っと・・・
> MSDN をよっく見てください。
> ほら、こんな一文が。
> > CREATE_NO_WINDOW
> > Windows NT/2000:このフラグは、コンソールアプリケーションを起動す> > る場合にのみ有効です。このフラグを指定すると、コンソールウィンドウ
> > なしでアプリケーションを実行します。
確認してみたのですが、私が使っているVisualStudio6.0のMSDNには見当たらなかったっす。
Onlineで見たら、ありました☆
やっぱり、Onlineで探さないとだめなんですね(^^;
.NETじゃないとこのフラグは使えないのかなぁ。
ちょっと試してみます。
> 例えば dir など、独立した exe でない DOS コマンドは CreateProcess
> では実行できませんので、そういう場合はコマンドインタプリタ
> (cmd.exe)を CreateProcess してやればいいということだと思います。
> net コマンドの場合は NET.EXE というファイルがあるので、インタプリタ> を介する必要はないかと思われますが。
そう言うことですか。
ありがとうございます。
> 出力ファイル名の部分はコマンドラインに渡してもできない気がします
> ので、別途リダイレクトしてやる必要があると思います。
> #「べっとりダイレクト」って変換された。ヤだなぁ…
すごいダイレクトですね(笑)
リダイレクトの方法が見つからなかったら、また聞いてしまうかもです(^^;
とりあえず、いろいろ試してみます☆
> MSDN をよっく見てください。
> ほら、こんな一文が。
> > CREATE_NO_WINDOW
実はこれではないです。
STARTUPINFO::dwFlagsとSTARTUPINFO::wShowWindowを適切に指定してやることで,
コマンドインタプリタのウィンドウを制御できます。
あくまでウィンドウを表示させないのであって,ウィンドウを作らないこととは別ですが……。
> 出力ファイル名の部分はコマンドラインに渡してもできない気がします
> ので、別途リダイレクトしてやる必要があると思います。
コマンドインタプリタを介すと,リダイレクトも処理されます。
リダイレクトする必要があるのであれば,コマンドインタプリタを経由したほうが楽です。
> やっぱり、Onlineで探さないとだめなんですね(^^;
できたら英語版を……。
日本語版は,いまだに時々翻訳抜けや誤訳があります。
#昔(VC++6の時代)に比べれば立派な訳ですが。
また,いまだにWindows 95/98とWindows NT/2000という分類になっているので,
いつの版をベースにしたかが不明,ということもあります。
> .NETじゃないとこのフラグは使えないのかなぁ。
.NETは関係ないです。
NT系であれば使えます。
どうもです。
YuOさん
> コマンドインタプリタを介すと,リダイレクトも処理されます。
> リダイレクトする必要があるのであれば,コマンドインタプリタを経由したほ
> うが楽です。
ということは・・・
char command[256];
STARTUPINFO si;
PROCESS_INFORMATION pi;
sprintf(command, "net user %s passwd /domain > c:\\tempmsg", m_UserName);
CreateProcess("cmd.exe", command, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
ってな感じでいいんですか?
試してみたんですが、空白のファイルが作成されただけなんす・・・(T_T)
よくないです。
コマンドラインをどうするかは、プロンプトから
cmd.exe /?
と打って確認してください。
ついでに…
STARTUPINFO構造体を正しく設定しないとならないかと。
シャノンさん、瀬戸っぷさん
ごめんなさい、この辺りの事よく分からなくて・・・
cmd.exe /A
と言うことですか?
また、STARTUPINFOについてもなんとも・・・
CreateProcessの使い方そのものを間違えているのかもしれません。
実際にしていることは、MFCで作成したダイアログのエディットボックスに入力をし、「更新」というボタンを押すと、このコマンドを実行し用としています。
このボタンの
OnButton1()
の中で、
char command[256];
STARTUPINFO si;
PROCESS_INFORMATION pi;
sprintf(command, "net user %s passwd /domain > c:\\tempmsg", m_UserName);
CreateProcess("cmd.exe", command, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
を実行しようとしていました。
なんか混乱してきちゃいました・・・
誰か助けてください・・・
とりあえず、cmd.exeのスイッチの件は他の方にしてもらうとして…
> char command[256];
> STARTUPINFO si;
> PROCESS_INFORMATION pi;
> sprintf(command, "net user %s passwd /domain > c:\\tempmsg", m_UserName);
> CreateProcess("cmd.exe", command, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
では、ゴミデータの入ったSTARTUPINFO構造体を使用しています。
構造体のメンバに設定されている値は不定ですので、最悪何が起こるか判りません。
(CreateProcess()が失敗するか、ヘンなふうに実行されるか……)
詳しくはMSDN等で各メンバを調べて貰うとして、とりあえず下記の方法でよろしいかと。
(丸ごとコピーするのではなく、ちゃんと調べて意味を把握して下さい)
ZeroMemory(si, sizeof(STARTUPINFO)); // 安全の為0クリア
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
# PROCESS_INFORMATION構造体の方はCreateProcess()が設定して返してくれるのでとりあえずは問題なし。
char command[256];
sprintf(command, "cmd.exe /C net user %s passwd /domain > c:\\tempmsg", m_UserName);
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
if( CreateProcess( NULL , command , NULL, NULL, FALSE, 0 , NULL, NULL, &si, &pi) )
{
CloseHandle(pi.hThread);
WaitForSingleObject( pi.hProcess, INFINITE );// プロセスの終了を待つ
CloseHandle(pi.hProcess);
}
WinExec(szBuf, SW_HIDE)
失敗^^;
互換性のためだけに残されているAPIですが、
WinExecをSW_HIDEで呼んであげるのが楽でいいですよ
ツイート | ![]() |