0

私は数時間グーグルで検索し、見つけたものすべてを試しましたが、うまくいかないようです.

私のコードは次のとおりです。

private static long _i;
private static readonly System.Timers.Timer Timer = new System.Timers.Timer(1000);

[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll")]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

[DllImport("user32.dll")]
private static extern int GetWindowModuleFileName(IntPtr hWnd, StringBuilder text, int count);

static void Main()
{
    Timer.Elapsed += Timer_Elapsed;
    Timer.AutoReset = true;
    Timer.Start();
    while (Timer.Enabled)
        Console.ReadLine();
}

static void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    Console.WriteLine("-|- - " + _i + " - -|-");   
    Console.WriteLine("WindowHandle: " + GetForegroundWindow());
    var buff = new StringBuilder(2048);
    GetWindowModuleFileName(GetForegroundWindow(), buff, 1024);
    Console.WriteLine("ModuleName: "  + Path.GetFileName(buff.ToString()));
    Console.WriteLine("-|- - | - -|-");
    _i++;    
}

このコードの出力は常に次のようになります。

-|- - 1 - -|-
WindowHandle: 8128962
ModuleName: ConsoleApplication.vshost.exe
-|- - | - -|-

しかし、Chrome や Fiddler などの別のアプリケーションをターゲットにした場合でも、実行可能なファイル名が常に出力されるか、ファイル名がまったく出力されません。私が見逃しているかもしれない問題はありますか?

4

2 に答える 2

1

追加の手順を 1 つ行う必要があります。foregroundwindow に属するプロセスを取得する必要があります。これはうまくいくかもしれません:

[Flags]
enum ProcessAccessFlags : uint
{
    All = 0x001F0FFF,
    Terminate = 0x00000001,
    CreateThread = 0x00000002,
    VMOperation = 0x00000008,
    VMRead = 0x00000010,
    VMWrite = 0x00000020,
    DupHandle = 0x00000040,
    SetInformation = 0x00000200,
    QueryInformation = 0x00000400,
    Synchronize = 0x00100000
}

    [DllImport("user32.dll")]
    private static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll")]
    private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

    [DllImport("user32.dll")]
    private static extern int GetWindowModuleFileName(IntPtr hWnd, StringBuilder text, int count);

    [DllImport("user32.dll")]
    private static extern IntPtr GetTopWindow(IntPtr hWnd);

    [DllImport("user32.dll")]
    private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint pid);

    [DllImport("kernel32.dll")]
    static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId);

    [DllImport("psapi.dll")]
    static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, [Out] StringBuilder lpBaseName, [In] [MarshalAs(UnmanagedType.U4)] int nSize);


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

    static void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        Console.WriteLine("-|- - " + _i + " - -|-");   
        Console.WriteLine("WindowHandle: " + GetForegroundWindow());
        uint pid;
        GetWindowThreadProcessId(GetForegroundWindow(), out pid);
        IntPtr proc = OpenProcess(ProcessAccessFlags.VMRead | ProcessAccessFlags.QueryInformation, true, pid);
        var buff = new StringBuilder(2048);
        GetModuleFileNameEx(proc, (IntPtr) 0, buff, 1024);
        Console.WriteLine("ModuleName: "  + Path.GetFileName(buff.ToString()));
        Console.WriteLine("-|- - | - -|-");
        _i++;
        CloseHandle(proc);
    }

これは基本的に、この C 回答の ac# 実装です。

于 2013-10-27T12:46:52.987 に答える
1

これには System.Management への参照を追加する必要があります - WMI を使用します

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
using System.Text;

namespace ConsoleApplication1
{
   class Program
   {
      private static long _i;
      private static readonly System.Timers.Timer Timer = new System.Timers.Timer( 1000 );
      [DllImport( "user32.dll" )]
      private static extern IntPtr GetForegroundWindow();

      [DllImport( "user32.dll" )]
      private static extern int GetWindowText( IntPtr hWnd, StringBuilder text, int count );

      [DllImport( "user32.dll" )]
      private static extern int GetWindowModuleFileName( IntPtr hWnd, StringBuilder text, int count );

      [DllImport( "user32.dll", SetLastError = true )]
      public static extern int GetWindowThreadProcessId( IntPtr hwnd, ref int lpdwProcessId );

      static void Main()
      {


         Timer.Elapsed += Timer_Elapsed;
         Timer.AutoReset = true;
         Timer.Start();
         while ( Timer.Enabled )
            Console.ReadLine();
      }

      static void Timer_Elapsed( object sender, System.Timers.ElapsedEventArgs e )
      {
         Console.WriteLine( "-|- - " + _i + " - -|-" );
         Console.WriteLine( "WindowHandle: " + GetForegroundWindow() );

         string name = GetProcessEXENameUsingWMI( GetProcess( GetForegroundWindow() ) );

         Console.WriteLine( "ModuleName: " + Path.GetFileName( name ) );

         Console.WriteLine( "-|- - | - -|-" );
         _i++;

      }

      private static string GetProcessEXENameUsingWMI( Process p )
      {
         ManagementObjectSearcher mos = new ManagementObjectSearcher( "SELECT ExecutablePath FROM Win32_Process WHERE ProcessId=" + p.Id.ToString() );
         ManagementObjectCollection moc = mos.Get();

         foreach ( ManagementObject mo in moc )
         {
            string executablePath = mo[ "ExecutablePath" ].ToString();
            return executablePath;
         }

         return "";
      }

      public static Process GetProcess( IntPtr hwnd )
      {
         int intID = 0;
         GetWindowThreadProcessId( hwnd, ref intID );
         return Process.GetProcessById( intID );
      }

   }
}
于 2013-10-27T12:34:51.007 に答える