0

動作するコードがいくつかありますが、遅すぎます。System.Management.ManagementObjectSearcherを使用して、「Select * from Win32_Process」のObjectQueryを実行します。次に、返されたリストを繰り返し、「GetOwner」を(InvokeMethodを介して)呼び出して、プロセスが検索しているユーザーによるものかどうかを確認します。次に、「Terminate」を呼び出します(これもInvokeMethodを介して)。

反復中に終了するプロセスを説明するための追加の例外処理を使用すると、これは機能しますが、これを実行する必要のある数千のプロセスがあるマシンでは、すべてのプロセスを反復するのに完全に1時間かかります。

ターゲットサーバーにフットプリントを持たない代替手段はありますか?リモート部分は、私たちが行っていることの鍵です。ローカルに移動する必要がある場合は、win32 apiのオプションがありますが、ローカルで実行するとWMIは十分に高速になると思います。

4

2 に答える 2

1

残念ながら、WMI はプロセスの所有者を取得するのに非常に時間がかかります。パフォーマンスを向上させたい場合は、WInAPi 関数OpenProcessTokenと を使用する必要がありますCloseHandle

このサンプルをチェック

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Security.Principal;
using System.Runtime.InteropServices;

namespace ConsoleApplicationTest
{
    class Program
    {
        static uint TOKEN_QUERY = 0x0008;

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle(IntPtr hObject);


        static void Main(string[] args)
        {
            foreach (Process p in Process.GetProcesses())
            {
                IntPtr TokenHandle = IntPtr.Zero;
                try
                {
                    OpenProcessToken(p.Handle, TOKEN_QUERY, out TokenHandle);
                    WindowsIdentity WinIdent = new WindowsIdentity(TokenHandle);
                    Console.WriteLine("Pid {0} Name {1} Owner {2}", p.Handle, p.ProcessName, WinIdent.Name);
                }
                catch (Exception Ex)
                {
                    Console.WriteLine("{0} in {1}", Ex.Message, p.ProcessName);
                }
                finally
                {
                    if (TokenHandle != IntPtr.Zero) { CloseHandle(TokenHandle); }
                }
            }
            Console.ReadKey();
        }
    }
}
于 2012-04-10T20:35:14.193 に答える
0

反復または呼び出しメソッドのどちらがゆっくりと動作するかはわかりません。おそらく後者だと思います。

  • wmi クエリを実行する代わりに、ManagementClass.GetInstances() を試すことはできますか?
  • 返された WMI インスタンスを反復処理し、それらをキューにキャッシュしてみてください。その後、複数のスレッドを作成できます。それぞれがキュー内のインスタンスを取得し、メソッドを呼び出します。
于 2012-04-10T20:18:18.910 に答える