检测Internet Explorer进程是否正在运行Flash Player
问题描述:
好的,这里有一点点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的变化。任何关于如何使用微软浏览器检测的线索?
答
确定我发现:
if ((process.ProcessName == "iexplore") && NativeMethods.ProcessContainsModule(process, "Flash32*"))
答
我已经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,那么代码会中断。
参考文献:
哥们,对于ProcessContainsModule代码是刚上的第一篇文章。 – 2016-11-25 20:26:31
哎呀,我的错。有趣的选择命名空间名称然后 – MickyD 2016-11-25 23:07:27