我创建了一个带有按钮的WinForms应用程序。当用户按下该按钮时,我想让我的应用程序检测是否打开了Web浏览器,如Chrome、IE或Firefox。
Message.Show("Browser Was Detected As Open",
"Success",
MessageBoxButtons.OK,
MessageBoxIcon.None);
而对于 "else if "浏览器没有被检测到,打开一个错误框,说 "请打开浏览器"。
我是C#新手,可能只是很简单的几行代码。
如果有谁能回答这个问题,非常感谢! 请包括#使用语句!
由于你写道你正在使用WinForms,我假设你是在Windows上。AFAIK有两种方法可以做到这一点 - 使用 Process
类或使用WinAPI。
我不会涉及WinAPI变体,因为它比较长,也比较复杂,而且我也没有真正使用它(大多数任务可以用纯C#来完成)。
你可以在你的 button.Click
事件处理程序。
private void DetectOpenBrowser()
{
var detector = new BrowserDetector();
if (detector.BrowserIsOpen())
{
MessageBox.Show(this, "Browser Was Detected As Open", "Success", MessageBoxButtons.OK);
}
else
{
MessageBox.Show(this, "Please Open Browser", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
BrowserDetector类。
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
internal class BrowserDetector
{
private readonly Dictionary<string, string> browsers = new Dictionary<string, string>
{
{
"firefox", "Mozilla Firefox"
},
{
"chrome", "Google Chrome"
},
{
"iexplore", "Internet Explorer"
},
{
"MicrosoftEdgeCP", "Microsoft Edge"
}
// add other browsers
};
public bool BrowserIsOpen()
{
return Process.GetProcesses().Any(this.IsBrowserWithWindow);
}
private bool IsBrowserWithWindow(Process process)
{
return this.browsers.TryGetValue(process.ProcessName, out var browserTitle) && process.MainWindowTitle.Contains(browserTitle);
}
}
笔记
我不确定是否所有浏览器的窗口标题中都有它们的名字,我只是检查了我现有的那些浏览器。
如果要添加其他浏览器,你需要在任务管理器中找到进程名,详情选项卡--比如火狐的条目是 "firefox.exe",所以进程名是 "firefox"。如果有不同的进程名,比如 "MicrosoftEdge "和 "MicrosoftEdgeCP",你就需要做一些实验来找出哪个进程有主窗口。
你可以参考下面的代码,通过windows API来检测浏览器是否被打开。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var RunningProcessPaths = ProcessFileNameFinderClass.GetAllRunningProcessFilePaths();
if (RunningProcessPaths.Contains("firefox.exe"))
{
MessageBox.Show("Firefox Browser Was Detected As Open",
"Success",
MessageBoxButtons.OK,
MessageBoxIcon.None);
}
if (RunningProcessPaths.Contains("chrome.exe"))
{
MessageBox.Show("Google chrome Browser Was Detected As Open",
"Success",
MessageBoxButtons.OK,
MessageBoxIcon.None);
}
if (RunningProcessPaths.Contains("iexplore.exe"))
{
MessageBox.Show("IE Browser Was Detected As Open",
"Success",
MessageBoxButtons.OK,
MessageBoxIcon.None);
}
//MicrosoftEdge.exe
if (RunningProcessPaths.Contains("MicrosoftEdge.exe"))
{
MessageBox.Show("Microsoft Edge Browser Was Detected As Open",
"Success",
MessageBoxButtons.OK,
MessageBoxIcon.None);
}
}
}
public class ProcessFileNameFinderClass
{
public static HashSet<string> GetAllRunningProcessFilePaths()
{
var allProcesses = System.Diagnostics.Process.GetProcesses();
HashSet<string> ProcessExeNames = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
foreach (Process p in allProcesses)
{
string processExePath = GetProcessExecutablePath(p);
ProcessExeNames.Add(System.IO.Path.GetFileName(processExePath));
}
return ProcessExeNames;
}
/// <summary>
/// Get executable path of running process
/// </summary>
/// <param name="Process"></param>
/// <returns></returns>
public static string GetProcessExecutablePath(Process Process)
{
try
{
if (Environment.OSVersion.Version.Major >= 6)
{
return GetExecutablePathAboveXP(Process.Id);// this gets the process file name without running as administrator
}
return Process.MainModule.FileName;// Vista and later this requires running as administrator.
}
catch
{
return "";
}
}
public static string GetExecutablePathAboveXP(int ProcessId)
{
int MAX_PATH = 260;
StringBuilder sb = new StringBuilder(MAX_PATH + 1);
IntPtr hprocess = OpenProcess(ProcessAccessFlags.PROCESS_QUERY_LIMITED_INFORMATION, false, ProcessId);
if (hprocess != IntPtr.Zero)
{
try
{
int size = sb.Capacity;
if (QueryFullProcessImageName(hprocess, 0, sb, ref size))
{
return sb.ToString();
}
}
finally
{
CloseHandle(hprocess);
}
}
return "";
}
[Flags()]
private enum ProcessAccessFlags : uint
{
PROCESS_ALL_ACCESS = 0x1f0fff,
PROCESS_TERMINATE = 0x1,
PROCESS_CREATE_THREAD = 0x2,
PROCESS_VM_OPERATION = 0x8,
PROCESS_VM_READ = 0x10,
PROCESS_VM_WRITE = 0x20,
PROCESS_DUP_HANDLE = 0x40,
PROCESS_SET_INFORMATION = 0x200,
PROCESS_SET_QUOTA = 0x100,
PROCESS_QUERY_INFORMATION = 0x400,
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000,
SYNCHRONIZE = 0x100000,
PROCESS_CREATE_PROCESS = 0x80,
PROCESS_SUSPEND_RESUME = 0x800
}
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool QueryFullProcessImageName(IntPtr hProcess, uint dwFlags, [Out(), MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpExeName, ref int lpdwSize);
[DllImport("kernel32.dll")]
private static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(IntPtr hHandle);
}
你可以用google chrome、IE、MicorsoftEdge和Firefox试试。
我试图使用上面的答案,但我不满意于检查所有正在运行的进程,也不满意于检查标题,因为本地化和可能由搜索引擎定制.这里是我的快速和有效的解决方案,它检查浏览器的存在,也检查它们是否至少有1个活动窗口。
internal static bool CheckIfAnyBrowserIsRunning()
{
bool answer = false;
foreach(var browser in GetBrowsers())
{
Process[] Processes = Process.GetProcessesByName(browser);
if (Processes.Length <= 0)
continue;
if (!Processes.Any(d=>d.MainWindowHandle != IntPtr.Zero))
continue;
answer = true;
break;
}
return answer;
}
internal static List<string> GetBrowsers()
{
return new List<string>() { "chrome", "msedge", "firefox" }; //add other browser process names
}