我使用了this answer中的代码来查看我的应用是否已在运行。如果它正在运行,我希望能够获取正在运行的应用程序并将其带到前面,以便用户可以看到它。
为了做到这一点,我可以使用Process.Name
属性并检查它,但如果另一个进程具有的名称不是我的应用程序,或者名称在修订版本之间发生变化,则可能无效。为了解决这个问题,我认为可以比较应用程序guid。我可以通过执行以下操作来获取我的应用程序:
string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly()
.GetCustomAttributes(typeof(GuidAttribute), false)
.GetValue(0)).Value.ToString();
有没有办法让应用程序guid或执行程序集guid正在运行的进程进行比较?
答案 0 :(得分:2)
事实证明,只需要在流程上使用Assembly.LoadFrom
即可。这可能会导致一些与访问有关的错误,所以要小心这些。我创建了以下类来检查应用程序是否正在运行以及是否将进程置于最前面。
请注意,下面的代码只是吞下了加载程序集的异常,这不是你想要的。就目前而言,就像我找到正确的例外情况一样。
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Threading;
namespace Helpers
{
public static class SingleInstance
{
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr handle);
[DllImport("User32.dll")]
private static extern bool ShowWindow(IntPtr handle, int nCmdShow);
[DllImport("User32.dll")]
private static extern bool IsIconic(IntPtr handle);
private const int SW_RESTORE = 9;
private static string _appGuid;
private static Mutex _mutex;
static SingleInstance()
{
_appGuid = GetAssemblyGuid(Assembly.GetExecutingAssembly());
}
public static bool IsAlreadyRunning(bool useGlobal)
{
//This code was taken from http://stackoverflow.com/a/229567/4631427
string mutexId;
if (useGlobal)
{
mutexId = String.Format("Global\\{}", _appGuid);
}
else
{
mutexId = String.Format("{}", _appGuid);
}
MutexAccessRule allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
MutexSecurity securitySettings = new MutexSecurity();
securitySettings.AddAccessRule(allowEveryoneRule);
bool createdNew;
_mutex = new Mutex(false, mutexId, out createdNew, securitySettings);
bool hasHandle = false;
try
{
hasHandle = _mutex.WaitOne(0, false);
if (!hasHandle)
{
return true;
}
}
catch (AbandonedMutexException)
{
hasHandle = true;
}
return false;
}
public static void ShowRunningApp()
{
Process current = Process.GetCurrentProcess();
foreach (Process process in Process.GetProcesses())
{
if (process.Id == current.Id)
{
continue;
}
try
{
Assembly assembly = Assembly.LoadFrom(process.MainModule.FileName);
string processGuid = GetAssemblyGuid(assembly);
if (_appGuid.Equals(processGuid))
{
BringProcessToFront(process);
return;
}
} catch { }
}
}
private static string GetAssemblyGuid(Assembly assembly)
{
object[] customAttribs = assembly.GetCustomAttributes(typeof(GuidAttribute), false);
if (customAttribs.Length < 1)
{
return null;
}
return ((GuidAttribute)(customAttribs.GetValue(0))).Value.ToString();
}
private static void BringProcessToFront(Process process)
{
IntPtr handle = process.MainWindowHandle;
if (IsIconic(handle))
{
ShowWindow(handle, SW_RESTORE);
}
SetForegroundWindow(handle);
}
}
}