none
Process.Start @ Windows7 RRS feed

  • 質問

  • いつもお世話になります。
    VisualC#2010、WindowsXPでの動作について質問があります。
    質問です。
    Windows7 VisualC#2010で開発しています。
    Process.Start("C:\Program Files\myprogram\myprogram\bin\Release\myprogram.exe");
    という行があり、これが実行されないという症状で困っています。
    WindowsXP VisualC#2010では実行できるのですが、なぜ7ではだめなんでしょう?
    ちなみに、ログインは管理者として行っています。
    2011年7月20日 5:50

回答

  • 例外は発生しません。
    try{}catch{}
    してもスルーです。
    さらに、タスクマネージャーでプロセスの生成を見ながら実行しているのですが、プロセスが生成されません。

    このような現象だと、起動したプロセスが一瞬で終了したと考えるのが自然ではないかと思います。
    Process.Start が Process のインスタンスを返しますが、これのプロパティを確認してみてはいかがでしょうか。(HasExited とか ExitTime とか ExitCode とか)
    また、ソースはそのままで myprogram.exe を myprogram2.exe とかにリネームしてから実行すると、正しく例外が発生するでしょうか?
    (個人的には起動したいプロセスのパスが変にエスケープされていそうなのが気になるのですが、実際のコードでは正しく記述されているんでしょうね、きっと。XP だと動いているみたいだし。)

    尚、UAC が原因という線はないと思います。
    一般ユーザーの権限で、

    Process.Start(@"Excel.exe のパス");
    

    と実行しても、普通に Excel が起動します。
    • 回答の候補に設定 山本春海 2011年7月28日 8:29
    • 回答としてマーク 山本春海 2011年7月29日 9:07
    2011年7月20日 7:45
  • 本当に生成されていないのですか? myprogram.exeは起動したものの、何らかのエラーですぐに終了してしまっていたりしませんか?

    Process.Start()が例外を発生させないのであれば、正常に動作できていてます。戻り値がProcessクラスインスタンスなので、これを確認してみてはどうでしょうか。プロセスIDや実行/終了状態なども取得できます。

    提示されたフォーラムスレッドでのやり取りでも「レジストリが変更できない」というのは「レジストリ変更を行うプログラムは起動している」上での話です。

    ちなみにProcess.Start()を呼び出した側(myprogram.exeを起動する親プロセス)はどんなプログラムですか?

    • 回答の候補に設定 山本春海 2011年7月28日 8:29
    • 回答としてマーク 山本春海 2011年7月29日 9:07
    2011年7月20日 7:46

すべての返信

  • 調べたところ、UACらしく、
    Process.Start(ProgramPath, UserID, securePassword, domain);
    と指定するらしいのです。
    このUserIDとPasswordに管理者のIDとパスワードを入れるところまではよいとして、

    System.Security.SecureString password = new System.Security.SecureString();
    foreach (char c in "password") password.AppendChar(c);
    Process.Start("programpath", "userID", password , "pcname");

    としたのですが、まだ実行できていません。
    どの辺りに穴がありますか?

    2011年7月20日 6:22
  • 「実行されない」とのことですが、では実際にはどうなるのでしょう? Process.Start()には問題があった場合に例外が発生することが記されています。例外発生するのですか? プロセスは起動するが表示されないとかですか?

    とにかく情報が不足しています。

    「調べたところ、UACらしく」とのことですが、何を調べてUACだと判断されたのですか?

    とにかく情報が不足しています。

    問題を解決すべく質問をしたいのでしたら、独り言ではなくきちんと現状を説明するようにしましょう。

    2011年7月20日 6:47
  • コメントありがとうございます。
    例外は発生しません。
    try{}catch{}
    してもスルーです。
    さらに、タスクマネージャーでプロセスの生成を見ながら実行しているのですが、プロセスが生成されません。
    UACは、Windows7のサイトを多数見たのと、msdnの関連の質問で見ました。
    http://social.msdn.microsoft.com/Forums/ja-JP/csharpgeneralja/thread/3f30b261-ee70-4a30-83f6-9fad6c728a96/
    です。
    2011年7月20日 7:24
  • 例外は発生しません。
    try{}catch{}
    してもスルーです。
    さらに、タスクマネージャーでプロセスの生成を見ながら実行しているのですが、プロセスが生成されません。

    このような現象だと、起動したプロセスが一瞬で終了したと考えるのが自然ではないかと思います。
    Process.Start が Process のインスタンスを返しますが、これのプロパティを確認してみてはいかがでしょうか。(HasExited とか ExitTime とか ExitCode とか)
    また、ソースはそのままで myprogram.exe を myprogram2.exe とかにリネームしてから実行すると、正しく例外が発生するでしょうか?
    (個人的には起動したいプロセスのパスが変にエスケープされていそうなのが気になるのですが、実際のコードでは正しく記述されているんでしょうね、きっと。XP だと動いているみたいだし。)

    尚、UAC が原因という線はないと思います。
    一般ユーザーの権限で、

    Process.Start(@"Excel.exe のパス");
    

    と実行しても、普通に Excel が起動します。
    • 回答の候補に設定 山本春海 2011年7月28日 8:29
    • 回答としてマーク 山本春海 2011年7月29日 9:07
    2011年7月20日 7:45
  • 本当に生成されていないのですか? myprogram.exeは起動したものの、何らかのエラーですぐに終了してしまっていたりしませんか?

    Process.Start()が例外を発生させないのであれば、正常に動作できていてます。戻り値がProcessクラスインスタンスなので、これを確認してみてはどうでしょうか。プロセスIDや実行/終了状態なども取得できます。

    提示されたフォーラムスレッドでのやり取りでも「レジストリが変更できない」というのは「レジストリ変更を行うプログラムは起動している」上での話です。

    ちなみにProcess.Start()を呼び出した側(myprogram.exeを起動する親プロセス)はどんなプログラムですか?

    • 回答の候補に設定 山本春海 2011年7月28日 8:29
    • 回答としてマーク 山本春海 2011年7月29日 9:07
    2011年7月20日 7:46
  • いろいろありがとうございました。
    次のようにしてみました。
    try{
    Process p = new Process;
    p.StartInfo.Filename = myprogram;
    p.Start();
    string ex = p.ExitCode.ToString();
    }catch{}

    これで1行ずつ実行したところ、たしかにおっしゃるように、情報をとれ、1秒で実行して終了していることを確認できました。

    が…、じっさいには処理は行われていなくて、どうにもなりませんでした。

    呼び出される方のプログラムをデバッグ起動してみると、問題なく処理されるのですが、外部から呼び出すと駄目なのです。
    こういうときって、どういうふうにデバッグするものなのでしょう?

    幸い(?)両方とも自分のプログラムなので、ソースを統合して、内部的に呼び出す処理にしてしまいました。
    動くには動いて、とりあえず解決です。
    ぜんぜんスマートでないですが…。
    ありがとうございました。

    2011年7月20日 10:20
  • 呼び出される方のプログラムをデバッグ起動してみると、問題なく処理されるのですが、外部から呼び出すと駄目なのです。
    こういうときって、どういうふうにデバッグするものなのでしょう?


    自分なら、呼び出される側の入り口で

    System.Diagnostics.Debugger.Break();
    

    とでもしてみるでしょうか。(C# の場合)
    C++ なら DebugBreak() を呼ぶとか。
    入り口で MessageBox みたいに一時停止するコードを入れておいて、強引にデバッガーでアタッチしに行くかもしれませんが。
    2011年7月20日 10:57
  • こんにちは、d-kot さん。

    MSDN フォーラムのご利用ありがとうございます。フォーラム オペレーターの山本です。

    問題の切り分けに有効なアドバイスをいただいているかと思いましたので、勝手ながら私のほうで回答としてマークさせていただきました。
    totojo さん、佐祐理 さん、アドバイスありがとうございます。

    いただいた情報の中で、解決に役立った投稿や、参考になる情報など有効な情報には回答としてマークすることをお願いしています。
    今後、同じ問題でこのスレッドを参照される方にも、有効な情報がわかりやすくなるかと思いますので、ご協力よろしくお願いいたしますね。

    すでにご自身で回避策をとられたようですが、以下のようなツールを使って、呼び出し元のプロセスや myprogram.exe の動作を解析してみると何かわかるかもしれません。
    また、佐祐理 さんからのアドバイスのように、呼び出し元のプロセスの情報などもあったほうが、もしかしたら有効な情報が得られるかもしれません。
    ご参考まで。

      Proccess Monitor
      http://technet.microsoft.com/ja-jp/sysinternals/bb896645
       
    今後とも、MSDN フォーラムをご利用よろしくお願いいたします。それでは。
                                                                                                                                               
    日本マイクロソフト株式会社 フォーラム オペレーター 山本 春海

    2011年7月29日 9:07

  • try{
      Process p = new Process;
      p.StartInfo.Filename = myprogram;
      p.Start();
      string ex = p.ExitCode.ToString();
    }catch{}

    終了を待つなら、p.WaitForExit() してからでないと、ExitCode で、InvalidOperationExceptionが発生しますよ。。

    質問ですが、呼び出されるプログラムの「処理」とは何でしょうか?
    また、処理が行われていないことを、どうやって確認されました?
    ExitCodeは何でしたか?

    原因としてありそうなのは・・・

    • 呼び出されるプログラムのコマンドライン出力がコマンドラインに表示されない。→BeginOutputReadLine を使用しましょう。
    • 呼び出す側から渡すコマンドライン引数が間違っている。→呼び出される側で、MessageBok などに表示してみましょう。
    • 本当に呼び出されているか確認するために、呼び出される側でMessageBoxなどを表示してみましょう。
    • たとえば呼び出される側で何かファイルを開く場合は注意です。「"something.txt"」などのように相対パスで書いてある場合は、「カレントディレクトリ」がどこかを確認しましょう。→呼び出す側からは、必ず絶対パスで渡しましょう。
    • →カレントディレクトリは、呼び出す側のプログラムがあるフォルダになっているか、OpenFileDialog等で移っている可能性があります。

    といったところでしょうか。

    2011年7月29日 17:31