2013-05-13 94 views
0

好的,這裏有一點點100萬美元的問題。我正在開發一個應用程序,用於檢查您的任何瀏覽器是否正在運行Flash應用程序。這是我的核心機實現:檢測Internet Explorer進程是否正在運行Flash Player

// Using CreateToolhelp32Snapshot allows to list all the modules loaded by a specific process. 
internal static Boolean ProcessContainsModule(Process process, String moduleMask) 
{ 
    IntPtr snapshotHandle; 

    if (Environment.Is64BitProcess) 
     snapshotHandle = CreateToolhelp32Snapshot((SnapshotFlags.Module | SnapshotFlags.Module32), (UInt32)process.Id); 
    else 
     snapshotHandle = CreateToolhelp32Snapshot(SnapshotFlags.Module, (UInt32)process.Id); 

    if (snapshotHandle == IntPtr.Zero) 
     return false; 

    Boolean result = false; 

    ModuleEntry entry = new ModuleEntry(); 
    entry.Size = ModuleEntry.SizeOf; 

    if (Module32First(snapshotHandle, ref entry)) 
    { 
     do 
     { 
      if (entry.ModuleName.FitsMask(moduleMask)) 
      { 
       result = true; 
       break; 
      } 

      entry = new ModuleEntry(); 
      entry.Size = ModuleEntry.SizeOf; 
     } 
     while (Module32Next(snapshotHandle, ref entry)); 
    } 

    CloseHandle(snapshotHandle); 

    return result; 
} 

// This is a simple wildcard matching implementation. 
public static Boolean FitsMask(this String value, String mask) 
{ 
    Regex regex; 

    if (!s_MaskRegexes.TryGetValue(mask, out regex)) 
     s_MaskRegexes[mask] = regex = new Regex(String.Concat('^', Regex.Escape(mask.Replace(".", "__DOT__").Replace("*", "__STAR__").Replace("?", "__QM__")).Replace("__DOT__", "[.]").Replace("__STAR__", ".*").Replace("__QM__", "."), '$'), RegexOptions.IgnoreCase); 

    return regex.IsMatch(value); 
} 

現在,Process Explorer是我的過程勘探中非常有用的。

與Chrome的檢測,這是非常簡單的:

if ((process.ProcessName == "chrome") && NativeMethods.ProcessContainsModule(process, "PepFlashPlayer.dll")) 

使用Firefox Detecthing這也很簡單:

if ((process.ProcessName.StartsWith("FlashPlayerPlugin")) && NativeMethods.ProcessContainsModule(process, "NPSWF32*")) 

像往常一樣,一切,當你正在尋找在Internet Explorer的變化。任何關於如何使用微軟瀏覽器檢測的線索?

回答

0

確定我發現:

if ((process.ProcessName == "iexplore") && NativeMethods.ProcessContainsModule(process, "Flash32*")) 
+0

哥們,對於ProcessContainsModule代碼是剛上的第一篇文章。 – 2016-11-25 20:26:31

+0

哎呀,我的錯。有趣的選擇命名空間名稱然後 – MickyD 2016-11-25 23:07:27

0

我已經Zarathos修改了代碼,使之能編譯,以及一些個人風格。

TL;博士:這適用於Firefox的,有時爲Chrome,而不是在所有的IE

首先,這裏的基本代碼:

using System; 
using System.Linq; 
using System.Runtime.InteropServices; 
using System.Diagnostics; 

#region pinvoke.net boilerplate 

[Flags] 
private enum SnapshotFlags : uint 
{ 
    HeapList = 0x00000001, 
    Process = 0x00000002, 
    Thread = 0x00000004, 
    Module = 0x00000008, 
    Module32 = 0x00000010, 
    Inherit = 0x80000000, 
    All = 0x0000001F, 
    NoHeaps = 0x40000000 
} 

private struct MODULEENTRY32 
{ 
    private const int MAX_PATH = 255; 
    internal uint dwSize; 
    internal uint th32ModuleID; 
    internal uint th32ProcessID; 
    internal uint GlblcntUsage; 
    internal uint ProccntUsage; 
    internal IntPtr modBaseAddr; 
    internal uint modBaseSize; 
    internal IntPtr hModule; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH + 1)] 
    internal string szModule; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH + 5)] 
    internal string szExePath; 
} 

[DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)] 
static extern IntPtr CreateToolhelp32Snapshot([In]UInt32 dwFlags, [In]UInt32 th32ProcessID); 

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

[DllImport("kernel32.dll")] 
static extern bool Module32First(IntPtr hSnapshot, ref MODULEENTRY32 lpme); 

[DllImport("kernel32.dll")] 
static extern bool Module32Next(IntPtr hSnapshot, ref MODULEENTRY32 lpme); 

#endregion 

static bool ProcessContainsModule(Process process, string searchTerm) 
{ 
    bool result = false; 

    //get handle to process 
    IntPtr snapshotHandle = Environment.Is64BitProcess ? 
     CreateToolhelp32Snapshot((UInt32)(SnapshotFlags.Module | SnapshotFlags.Module32), (UInt32)process.Id) : 
     CreateToolhelp32Snapshot((UInt32)SnapshotFlags.Module, (UInt32)process.Id); 
    if (snapshotHandle == IntPtr.Zero) 
    { 
     return result; 
    } 

    //walk the module list 
    try 
    { 
     MODULEENTRY32 entry = new MODULEENTRY32() { dwSize = (uint)Marshal.SizeOf(typeof(MODULEENTRY32)) }; 

     if (Module32First(snapshotHandle, ref entry)) 
     { 
      do 
      { 
       if (entry.szModule.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0) 
       { 
        result = true; 
        break; 
       } 

       entry = new MODULEENTRY32() { dwSize = (uint)Marshal.SizeOf(typeof(MODULEENTRY32)) }; 
      } 
      while (Module32Next(snapshotHandle, ref entry)); 
     } 

     return result; 
    } 
    finally 
    { 
     CloseHandle(snapshotHandle); 
    } 
} 

您可以使用它像這樣:

static bool IsFlashLoadedInFirefox() 
{ 
    return Process.GetProcessesByName("plugin-container").Any(x => ProcessContainsModule(x, "NPSWF")); 
} 

static bool IsFlashLoadedInInternetExplorer() 
{ 
    //This doesn't work. For some reason can't get modules from child processes 
    return Process.GetProcessesByName("iexplore").Any(x => ProcessContainsModule(x, "Flash32")); 
} 

static bool IsFlashLoadedInChrome() 
{ 
    //Doesn't work reliably. See description. 
    return Process.GetProcessesByName("chrome").Any(x => ProcessContainsModule(x, "pepflashplayer")); 
} 

正如在評論中指出,只有火狐似乎可靠地工作。在IE(IE11)的情況下,Module32First()出於某種原因失敗。在Chrome中的情況下,事情變得更有趣一些:

  • 如果一個新的標籤導航到youtube.com或YouTube視頻代碼工作
  • 如果一個新的選項卡瀏覽到播放列表但是,在YouTube上,代碼失敗,因爲pepFlashPlayer.dll不在該進程的模塊列表中(使用ProcessExplorer進行檢查)。而且,如果您繼續瀏覽其他非播放列表的YouTube視頻,它仍然不會顯示。

請注意,這種檢查進程加載的DLL的方法非常脆弱,如果任何瀏覽器決定更改加載的DLL或加載的DLL,那麼代碼會中斷。

參考文獻:

  1. http://pinvoke.net/default.aspx/kernel32.createtoolhelp32snapshot
  2. http://pinvoke.net/default.aspx/kernel32/Module32First.html
  3. http://pinvoke.net/default.aspx/kernel32/Module32Next.html
相關問題