none
Windows Vistaにおける実行中のすべてのプロセスを取得について RRS feed

  • 質問

  • 以下の2文ともWindowsXXPでは問題なく、正常に動作しますが、WindowsVistaでは例外が発生すします。

    Windows Vistaでプロセスを取得する際の手法が変更されたので動作しないと思いますが、具体的な変更方法が

    わかりません。正常に動作するためにどうすればいいのかをご存知の方教えてください。

     

    <例外発生箇所>

    ・System.Diagnostics.Process[] ps =  System.Diagnostics.Process.GetProcesses();

    ・Process[] localAll = Process.GetProcesses();

    2007年4月12日 1:58

すべての返信

  • >例外が発生すします
    どのような例外でしょうか?

    Vistaとなると、やはりUAC関連でしょうかね。
    →一度「管理者として実行」してみるとか。
    2007年4月12日 2:57
  • 簡単に XP, Vista ともに試してみましたが、私の環境では問題なく実行できてますね。

    Vista 上の VS でビルドして、実行ファイルを直接実行(標準ユーザ権限で)も確認しました。

     

    蒼の洞窟さんも書かれているように、どんな例外が発生するのかなど、もう少し詳しく書きましょう。

    また、Process.GetProcesses() の前後のソースコードなども書かれると何かわかるかもしれません。

     

    ちなみに、私のためしたソースは下記の通りです。

     

    private void button1_Click(object sender, EventArgs e)

    {

      System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcesses();

      foreach (System.Diagnostics.Process p in ps)

      {

        string psName = p.ProcessName;

      }

    }


     

    2007年4月12日 3:29
  • たしかに、そのとおりです。前項でご指摘いただいたユーザアクセス制御を

    コントロールパネルから一時的にOFFにするとプログラムは例外を起こさず動作しました。

    原因はわかりました。ちなみにエラーメッセージとサンプルのテストコードは以下の通りです。

     

    <エラーメッセージ>

    System.InvalidOperationException' のハンドルされていない例外が system.dll で発生しました。

    追加情報 : リモート コンピュータからプロセス情報を取得できませんでした。

     

    <サンプルコードのテストコード>

    using System;

     

    namespace ConsoleApplication1

    {

            /// <summary>

            /// Class1 の概要の説明です。

            /// </summary>

            class Class1

            {

                    /// <summary>

                    /// アプリケーションのメイン エントリ ポイントです。

                    /// </summary>

                    [STAThread]

                    static void Main(string[] args)

                    {

                           

                            System.Diagnostics.Process[] ps =

                                    System.Diagnostics.Process.GetProcesses();

     

                            //配列から1つずつ取り出す

                            foreach (System.Diagnostics.Process p in ps)

                            {

                                    try

                                    {

                                            //プロセス名を出力する

                                            Console.WriteLine("プロセス名: " + p.ProcessName);

                                            //ID

                                            Console.WriteLine(p.Id);

                                            //合計プロセッサ時間

                                            Console.WriteLine(p.TotalProcessorTime);

                                            //物理メモリ使用量

                                            Console.WriteLine(p.WorkingSet);

                                            //.NET Framework 2.0以降では次のようにする

                                            //Console.WriteLine(p.WorkingSet64);

                                            //メインモジュールのパス

                                            Console.WriteLine("パス: " + p.MainModule.FileName);

                                    }

                                    catch

                                    {

                                    }

                            }

     

                            //

                            // TODO: アプリケーションを開始するコードをここに追加してください。

                            //

                    }

            }

    }

     

    2007年4月12日 20:42
  •  ゼブラ さんからの引用
    <例外発生箇所>

    ・System.Diagnostics.Process[] ps =  System.Diagnostics.Process.GetProcesses();

    ・Process[] localAll = Process.GetProcesses();

     

    と書かれていますが、実際には Process.GetProcesses では例外は発生していないですよね。

    例外が発生するのは、正確にはゼブラさんのサンプルコードでいうと

     

     ゼブラ さんからの引用
    //合計プロセッサ時間

    Console.WriteLine(p.TotalProcessorTime);

     

    の箇所で、それも全てのプロセスが対象となるわけでなく、

    自分以外のユーザで実行されているプロセスの情報を取得する場合に発生していると思います。

    (ちなみに、プロセス名と ID に関しては全てのプロセスで問題なく取得できるようです)

     

    Windows Vista でタスクマネージャを実行して「プロセス」タブを開くと、

    「すべてのユーザーのプロセスを表示」

    というボタンがあり、このコマンドを実行するには UAC の対象となり権限昇格が必要なことが、

    ボタンに表示されたシールドアイコンからわかります。

     

    つまり、Process.GetProcesses で取得したプロセス全ての情報を列挙したい場合には

    アプリケーションの権限昇格が必要ということでしょう。

     

    ほかのユーザーの下で実行されているプロセスの情報は不要であるなら、

    try ~ catch で例外処理して区別すれば UAC 昇格は不要とは思います。

    2007年4月13日 7:30