将参数传递给同一应用程序的另一个实例
Passing argument to another instance of the same application
我的小应用程序有严重问题;基本上很容易理解:
我的软件,打开后,一切正常。
我想专注于打开另一个实例(我的意思是再次打开.exe),检查它是否已经打开。如果不是简单地启动应用程序,但如果它已经是 运行(也就是第二个或更多实例)"simply" 将输入参数(args 字符串数组)传递给第一个实例,这将适当地处理它。
这是我的 program.cs
static class Program
{
static Mutex mutex = new Mutex(true, "{blabla}");
[STAThread]
static void Main(String[] args)
{
if (mutex.WaitOne(TimeSpan.Zero, true))
{
//First Instance!
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
CALL A MY STATIC METHOD, DO SOME THINGS
Application.Run(new Form1());
}
finally
{
mutex.ReleaseMutex();
}
}
else
{
//Not-so-first instance!
CALL A STATIC METHOD,
DO OTHER THINGS LIKE COMUNICATE WITH FIRST INSTANCE
SIMPLY CLOSE.
}
}
}
如果它已经打开但(当然)它不能与主实例进行任何通信,这将仅识别(使用互斥量)。
我已经尝试了很多东西,但我无法让它工作。
我试过 this 但我真的不明白(在浪费了很多时间之后)如何放置我的 "first time" 代码和 "already running" 代码。
也试过MSMQ,但我做不到。
有人可以帮助我吗?这是一个基本的软件,可以做一些非常基本的事情,但我花了一天时间让它按照我想要的方式工作!
使用Mutex.
// Generate your GUID and put it here
private const string ProgramRunningGuid = "BD2023EE-F7B3-47B8-8C76-32668196E4D3";
private Mutex _mutex;
private bool IsProgramRunning()
{
bool createdNew;
// It returns a bool value determining if a Mutex that created is new
// If the program is already running mutex wouldn't be new
_mutex = new Mutex(true, ProgramRunningGuid, out createdNew);
return !createdNew;
}
程序退出时需要释放互斥量:
_needlesRunningMutex.ReleaseMutex();
如果您想关注已经 运行 的应用程序实例,您可以在此处使用有效解决方案查看我的答案:
如果您只需要共享一些 bool 参数来确定事物是打开还是关闭,您可以为它们中的每一个使用互斥量。
如果您需要在启动时将参数传递给您的 .exe,请检查这个问题:
如果您需要在 运行 应用程序的两个实例之间进行连续通信,请使用 MSMQ。如果有任何问题,我会尽力帮助你。
在这里查看如何使用 MSMQ:https://github.com/IvanYurchenko/MSMQSample
最简单的通信方式之一是从第二个实例向第一个实例发送 Windows 消息。第二个实例将使用 PostMessage 发送消息,第一个实例将重写 Form1 的 WndProc 方法来处理消息。
这里有一个例子:
Send message to a Windows process (not its main window)
该问题还有一个答案,使用管道(和 WCF)进行通信。
进程间通信有多种形式。您使用哪一个取决于您的需要,例如 Windows 消息不能携带大量信息,而管道可以以非常高的速度传输数据。
更新
一个简单的替代方案可能是 IPCChannel 。这允许您在第一个实例中创建一个可以被第二个实例调用的对象。您可以在该对象上创建一个方法并将您的数据作为参数传递
我通过文本文件传递参数(我相信你可以从 VB.NET/pseudocode 翻译过来):
Private _uniqueEventName As String
Private _uniqueMutexName As String
Private _eventWaitHandle As EventWaitHandle
Private _mutex As Mutex
Private Sub ensureSingleInstance()
_uniqueEventName = "{0ae64101-e630-4221-bf10-123fdddd5ab2}" + Assembly.GetEntryAssembly().GetName().Name
_uniqueMutexName = "{03169a07-793b-48c6-8ceb-1232388cb69a}" + Assembly.GetEntryAssembly().GetName().Name
Dim isOwned As Boolean
_mutex = New Mutex(True, _uniqueMutexName, isOwned)
_eventWaitHandle = New EventWaitHandle(False, EventResetMode.AutoReset, _uniqueEventName)
GC.KeepAlive(_mutex)
If isOwned Then
Dim thread As Thread = New Thread(
Sub()
While _eventWaitHandle.WaitOne()
Application.Dispatcher.BeginInvoke(
Sub()
' ****************************************************
' READ AND PROCESS THE ARGUMENTS FROM C:\MYAPPARGS.TXT
' ****************************************************
If Not Application.MainWindow Is Nothing Then
_loggingDAL.Log("Activating main window")
If (Application.MainWindow.WindowState = WindowState.Minimized Or Application.MainWindow.Visibility = Visibility.Hidden) Then
Application.MainWindow.Show()
Application.MainWindow.WindowState = WindowState.Normal
End If
Application.MainWindow.Activate()
Dim topMost As Boolean = Application.MainWindow.Topmost
Application.MainWindow.Topmost = True
Application.MainWindow.Topmost = topMost
Application.MainWindow.Focus()
End If
End Sub)
End While
End Sub)
thread.IsBackground = True
thread.Start()
Else
_loggingDAL.Log("There is already an instance running -> switching and quitting")
' ***************************************
' WRITE THE ARGUMENTS TO C:\MYAPPARGS.TXT
' ***************************************
_eventWaitHandle.Set()
Application.Shutdown()
End If
End Sub
我的小应用程序有严重问题;基本上很容易理解:
我的软件,打开后,一切正常。
我想专注于打开另一个实例(我的意思是再次打开.exe),检查它是否已经打开。如果不是简单地启动应用程序,但如果它已经是 运行(也就是第二个或更多实例)"simply" 将输入参数(args 字符串数组)传递给第一个实例,这将适当地处理它。
这是我的 program.cs
static class Program
{
static Mutex mutex = new Mutex(true, "{blabla}");
[STAThread]
static void Main(String[] args)
{
if (mutex.WaitOne(TimeSpan.Zero, true))
{
//First Instance!
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
CALL A MY STATIC METHOD, DO SOME THINGS
Application.Run(new Form1());
}
finally
{
mutex.ReleaseMutex();
}
}
else
{
//Not-so-first instance!
CALL A STATIC METHOD,
DO OTHER THINGS LIKE COMUNICATE WITH FIRST INSTANCE
SIMPLY CLOSE.
}
}
}
如果它已经打开但(当然)它不能与主实例进行任何通信,这将仅识别(使用互斥量)。
我已经尝试了很多东西,但我无法让它工作。
我试过 this 但我真的不明白(在浪费了很多时间之后)如何放置我的 "first time" 代码和 "already running" 代码。
也试过MSMQ,但我做不到。
有人可以帮助我吗?这是一个基本的软件,可以做一些非常基本的事情,但我花了一天时间让它按照我想要的方式工作!
使用Mutex.
// Generate your GUID and put it here
private const string ProgramRunningGuid = "BD2023EE-F7B3-47B8-8C76-32668196E4D3";
private Mutex _mutex;
private bool IsProgramRunning()
{
bool createdNew;
// It returns a bool value determining if a Mutex that created is new
// If the program is already running mutex wouldn't be new
_mutex = new Mutex(true, ProgramRunningGuid, out createdNew);
return !createdNew;
}
程序退出时需要释放互斥量:
_needlesRunningMutex.ReleaseMutex();
如果您想关注已经 运行 的应用程序实例,您可以在此处使用有效解决方案查看我的答案:
如果您只需要共享一些 bool 参数来确定事物是打开还是关闭,您可以为它们中的每一个使用互斥量。
如果您需要在启动时将参数传递给您的 .exe,请检查这个问题:
如果您需要在 运行 应用程序的两个实例之间进行连续通信,请使用 MSMQ。如果有任何问题,我会尽力帮助你。
在这里查看如何使用 MSMQ:https://github.com/IvanYurchenko/MSMQSample
最简单的通信方式之一是从第二个实例向第一个实例发送 Windows 消息。第二个实例将使用 PostMessage 发送消息,第一个实例将重写 Form1 的 WndProc 方法来处理消息。
这里有一个例子: Send message to a Windows process (not its main window)
该问题还有一个答案,使用管道(和 WCF)进行通信。
进程间通信有多种形式。您使用哪一个取决于您的需要,例如 Windows 消息不能携带大量信息,而管道可以以非常高的速度传输数据。
更新 一个简单的替代方案可能是 IPCChannel 。这允许您在第一个实例中创建一个可以被第二个实例调用的对象。您可以在该对象上创建一个方法并将您的数据作为参数传递
我通过文本文件传递参数(我相信你可以从 VB.NET/pseudocode 翻译过来):
Private _uniqueEventName As String
Private _uniqueMutexName As String
Private _eventWaitHandle As EventWaitHandle
Private _mutex As Mutex
Private Sub ensureSingleInstance()
_uniqueEventName = "{0ae64101-e630-4221-bf10-123fdddd5ab2}" + Assembly.GetEntryAssembly().GetName().Name
_uniqueMutexName = "{03169a07-793b-48c6-8ceb-1232388cb69a}" + Assembly.GetEntryAssembly().GetName().Name
Dim isOwned As Boolean
_mutex = New Mutex(True, _uniqueMutexName, isOwned)
_eventWaitHandle = New EventWaitHandle(False, EventResetMode.AutoReset, _uniqueEventName)
GC.KeepAlive(_mutex)
If isOwned Then
Dim thread As Thread = New Thread(
Sub()
While _eventWaitHandle.WaitOne()
Application.Dispatcher.BeginInvoke(
Sub()
' ****************************************************
' READ AND PROCESS THE ARGUMENTS FROM C:\MYAPPARGS.TXT
' ****************************************************
If Not Application.MainWindow Is Nothing Then
_loggingDAL.Log("Activating main window")
If (Application.MainWindow.WindowState = WindowState.Minimized Or Application.MainWindow.Visibility = Visibility.Hidden) Then
Application.MainWindow.Show()
Application.MainWindow.WindowState = WindowState.Normal
End If
Application.MainWindow.Activate()
Dim topMost As Boolean = Application.MainWindow.Topmost
Application.MainWindow.Topmost = True
Application.MainWindow.Topmost = topMost
Application.MainWindow.Focus()
End If
End Sub)
End While
End Sub)
thread.IsBackground = True
thread.Start()
Else
_loggingDAL.Log("There is already an instance running -> switching and quitting")
' ***************************************
' WRITE THE ARGUMENTS TO C:\MYAPPARGS.TXT
' ***************************************
_eventWaitHandle.Set()
Application.Shutdown()
End If
End Sub