C# Mutex 如何多次停止我的控制台应用程序 运行
C# Mutex how to stop my console app running multiple times
我有一个控制台程序,没有那么复杂,但同时也不是 hello world 程序。我只有两个项目,第一个有几个 类。它不是多线程的,而是关于调用 restful API 等。
事情是这样的:我试图让我的应用程序检查它是否运行两次(这非常重要)。我认为这在某种程度上是可行的,但结果却极其复杂。
不幸的是,我发现的唯一例子并没有说明如何使用这项技术。下面的代码对我来说很复杂,我不知道如何将它插入我的 Main.因此,问题。
下面的代码(不是我的,我在这里找到的:https://www.codeproject.com/Articles/3014/Single-Process-Instance-Object)
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Reflection;
namespace SpecialServices
{
//SingleProgamInstance uses a mutex synchronization
//object to ensure that only one copy of process is running
//at a particular time. It also allows for UI identification
// of the intial process by bringing that window to the foreground.
public class SingleProgramInstance : IDisposable
{
//Win32 API calls necesary to raise an unowned processs main window
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd,int nCmdShow);
[DllImport("user32.dll")]
private static extern bool IsIconic(IntPtr hWnd);
private const int SW_RESTORE = 9;
//private members
private Mutex _processSync;
private bool _owned = false;
public SingleProgramInstance()
{
//Initialize a named mutex and attempt to
// get ownership immediately
_processSync = new Mutex(
true, // desire intial ownership
Assembly.GetExecutingAssembly().GetName().Name,
out _owned);
}
public SingleProgramInstance(string identifier)
{
//Initialize a named mutex and attempt to
// get ownership immediately.
//Use an addtional identifier to lower
// our chances of another process creating
// a mutex with the same name.
_processSync = new Mutex(
true, // desire intial ownership
Assembly.GetExecutingAssembly().GetName().Name + identifier,
out _owned);
}
~SingleProgramInstance()
{
//Release mutex (if necessary)
//This should have been accomplished using Dispose()
Release();
}
public bool IsSingleInstance
{
//If we don't own the mutex than
// we are not the first instance.
get {return _owned;}
}
public void RaiseOtherProcess()
{
Process proc = Process.GetCurrentProcess();
// Using Process.ProcessName does not function properly when
// the actual name exceeds 15 characters. Using the assembly
// name takes care of this quirk and is more accruate than
// other work arounds.
string assemblyName =
Assembly.GetExecutingAssembly().GetName().Name;
foreach (Process otherProc in
Process.GetProcessesByName(assemblyName))
{
//ignore "this" process
if (proc.Id != otherProc.Id)
{
// Found a "same named process".
// Assume it is the one we want brought to the foreground.
// Use the Win32 API to bring it to the foreground.
IntPtr hWnd = otherProc.MainWindowHandle;
if (IsIconic(hWnd))
{
ShowWindowAsync(hWnd,SW_RESTORE);
}
SetForegroundWindow(hWnd);
break;
}
}
}
private void Release()
{
if (_owned)
{
//If we own the mutex than release it so that
// other "same" processes can now start.
_processSync.ReleaseMutex();
_owned = false;
}
}
#region Implementation of IDisposable
public void Dispose()
{
//release mutex (if necessary) and notify
// the garbage collector to ignore the destructor
Release();
GC.SuppressFinalize(this);
}
#endregion
}
}
如果您对上述内容有任何帮助,我们将不胜感激;非常感谢。
试试这个:
private void CloseDuplicateApplications()
{
string ProgramTitle = System.Diagnostics.Process.GetCurrentProcess().MainWindowTitle;
System.Diagnostics.Process[] Processes = System.Diagnostics.Process.GetProcesses();
for (int i = 0; i < Processes.Length; i++)
{
if (Processes[i].MainWindowTitle == ProgramTitle)
{
Processes[i].CloseMainWindow();
}
}
}
目前该程序只是关闭所有重复的程序,但是如果您需要终止重复的程序,请替换此行:
Processes[i].CloseMainWindow();
与:
Processes[i].Kill();
如何使用示例代码。
获取示例代码(它的一个文件)并将其添加到您的项目中(作为一个单独的 .cs 文件)
现在在您的程序启动时添加
using(var spi = new SpecialServices.SingleProgramInstance("x5k6yz"))
{
if (!spi.IsSingleInstance){
Console.WriteLine("another copy is running");
return;
}
}
请注意,我没有尝试示例中的代码,我认为它可以工作。
编辑。好的测试,它工作正常
我有一个控制台程序,没有那么复杂,但同时也不是 hello world 程序。我只有两个项目,第一个有几个 类。它不是多线程的,而是关于调用 restful API 等。 事情是这样的:我试图让我的应用程序检查它是否运行两次(这非常重要)。我认为这在某种程度上是可行的,但结果却极其复杂。 不幸的是,我发现的唯一例子并没有说明如何使用这项技术。下面的代码对我来说很复杂,我不知道如何将它插入我的 Main.因此,问题。 下面的代码(不是我的,我在这里找到的:https://www.codeproject.com/Articles/3014/Single-Process-Instance-Object)
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Reflection;
namespace SpecialServices
{
//SingleProgamInstance uses a mutex synchronization
//object to ensure that only one copy of process is running
//at a particular time. It also allows for UI identification
// of the intial process by bringing that window to the foreground.
public class SingleProgramInstance : IDisposable
{
//Win32 API calls necesary to raise an unowned processs main window
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd,int nCmdShow);
[DllImport("user32.dll")]
private static extern bool IsIconic(IntPtr hWnd);
private const int SW_RESTORE = 9;
//private members
private Mutex _processSync;
private bool _owned = false;
public SingleProgramInstance()
{
//Initialize a named mutex and attempt to
// get ownership immediately
_processSync = new Mutex(
true, // desire intial ownership
Assembly.GetExecutingAssembly().GetName().Name,
out _owned);
}
public SingleProgramInstance(string identifier)
{
//Initialize a named mutex and attempt to
// get ownership immediately.
//Use an addtional identifier to lower
// our chances of another process creating
// a mutex with the same name.
_processSync = new Mutex(
true, // desire intial ownership
Assembly.GetExecutingAssembly().GetName().Name + identifier,
out _owned);
}
~SingleProgramInstance()
{
//Release mutex (if necessary)
//This should have been accomplished using Dispose()
Release();
}
public bool IsSingleInstance
{
//If we don't own the mutex than
// we are not the first instance.
get {return _owned;}
}
public void RaiseOtherProcess()
{
Process proc = Process.GetCurrentProcess();
// Using Process.ProcessName does not function properly when
// the actual name exceeds 15 characters. Using the assembly
// name takes care of this quirk and is more accruate than
// other work arounds.
string assemblyName =
Assembly.GetExecutingAssembly().GetName().Name;
foreach (Process otherProc in
Process.GetProcessesByName(assemblyName))
{
//ignore "this" process
if (proc.Id != otherProc.Id)
{
// Found a "same named process".
// Assume it is the one we want brought to the foreground.
// Use the Win32 API to bring it to the foreground.
IntPtr hWnd = otherProc.MainWindowHandle;
if (IsIconic(hWnd))
{
ShowWindowAsync(hWnd,SW_RESTORE);
}
SetForegroundWindow(hWnd);
break;
}
}
}
private void Release()
{
if (_owned)
{
//If we own the mutex than release it so that
// other "same" processes can now start.
_processSync.ReleaseMutex();
_owned = false;
}
}
#region Implementation of IDisposable
public void Dispose()
{
//release mutex (if necessary) and notify
// the garbage collector to ignore the destructor
Release();
GC.SuppressFinalize(this);
}
#endregion
}
}
如果您对上述内容有任何帮助,我们将不胜感激;非常感谢。
试试这个:
private void CloseDuplicateApplications()
{
string ProgramTitle = System.Diagnostics.Process.GetCurrentProcess().MainWindowTitle;
System.Diagnostics.Process[] Processes = System.Diagnostics.Process.GetProcesses();
for (int i = 0; i < Processes.Length; i++)
{
if (Processes[i].MainWindowTitle == ProgramTitle)
{
Processes[i].CloseMainWindow();
}
}
}
目前该程序只是关闭所有重复的程序,但是如果您需要终止重复的程序,请替换此行:
Processes[i].CloseMainWindow();
与:
Processes[i].Kill();
如何使用示例代码。
获取示例代码(它的一个文件)并将其添加到您的项目中(作为一个单独的 .cs 文件)
现在在您的程序启动时添加
using(var spi = new SpecialServices.SingleProgramInstance("x5k6yz"))
{
if (!spi.IsSingleInstance){
Console.WriteLine("another copy is running");
return;
}
}
请注意,我没有尝试示例中的代码,我认为它可以工作。
编辑。好的测试,它工作正常