我有一个在后台运行的应用程序(隐藏了控制台应用程序)。我想说,如果用户试图打开这个应用程序的多个实例(点击* .exe文件),新的将关闭,并显示当前正在运行的实例。
这是我尝试过的:
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_HIDE = 0;
const int SW_SHOW = 5;
bool moreThanOne = false;
string processName = System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location);
System.Diagnostics.Process[] arr = System.Diagnostics.Process.GetProcesses();
Console.WriteLine("Looking for: " + processName);
foreach (var a in arr)
{
Console.WriteLine(a.ProcessName);
if (a.ProcessName == processName)
{
Console.WriteLine("---------------------------------");
if (moreThanOne)
{
IntPtr handle = a.MainWindowHandle;
ShowWindow(handle, SW_SHOW);
Console.WriteLine("close!!!!1111");
Environment.Exit(0);
}
else
{
moreThanOne = true;
}
}
}
它目前无效,我不知道为什么。始终可以正确找到进程,但是“取消隐藏”以前打开的应用程序存在一些问题。我做错了吗?
答案 0 :(得分:1)
为了避免用户启动你的应用程序两次更好的想法使用Mutex而不是检查进程列表(如果另一个用户再次启动你的应用程序而第一个没有权限看到它的图像)。
You Main变得像那样(使用winform)
[STAThread]
static void Main()
{
try
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
using (new SingleGlobalInstance(TIMEOUT_START))
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
_mainProgram = new frmMainProgram();
ApplicationContext appCtx = new ApplicationContext(_mainProgram);
Application.Run(appCtx);
}
}
catch (Exception unhandled)
{
Program.UnhandledExceptionHandler(null, (new UnhandledExceptionEventArgs(unhandled, true)));
}
}
然后隐藏互斥逻辑的对象
public class SingleGlobalInstance : IDisposable
{
public bool hasHandle = false;
Mutex mutex;
private void InitMutex()
{
string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();
string mutexId = string.Format("Global\\{{{0}}}", appGuid);
mutex = new Mutex(false, mutexId);
var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
var securitySettings = new MutexSecurity();
securitySettings.AddAccessRule(allowEveryoneRule);
mutex.SetAccessControl(securitySettings);
}
public SingleGlobalInstance(int timeOut)
{
InitMutex();
try
{
if (timeOut < 0)
hasHandle = mutex.WaitOne(Timeout.Infinite, false);
else
hasHandle = mutex.WaitOne(timeOut, false);
if (hasHandle == false)
throw new TimeoutException("Timeout waiting for exclusive access on SingleInstance");
}
catch (AbandonedMutexException)
{
hasHandle = true;
}
}
public void Dispose()
{
if (mutex != null)
{
if (hasHandle)
mutex.ReleaseMutex();
mutex.Dispose();
}
}
}
如果你需要超时,你可以在这里抛出特殊异常并取消隐藏隐藏的应用程序(从获得超时的应用程序中退出)