我有一個WinForms應用程序,如果已經有一個實例運行&用戶試圖旋轉另一個實例,我通過在調用Application.Run()之前檢查一個Mutex來停止它。這部分工作得很好。我想要做的是在殺死新進程之前,將應用程序新實例的消息(以及字符串形式的一段數據)傳遞給現有實例。如何從託管應用程序的一個實例向另一個實例發送消息?
我試過調用PostMessage,並且確實收到了正在運行的應用程序的消息,但是我在lparam中傳遞的字符串失敗了(是的,我已經檢查過以確保我傳遞的是一個好的字符串開始)。我怎樣才能最好地做到這一點?
static class Program
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool PostMessage(int hhwnd, uint msg, IntPtr wparam, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern uint RegisterWindowMessage(string lpString);
private const int HWND_BROADCAST = 0xffff;
static uint _wmJLPC = unchecked((uint)-1);
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
_wmJLPC = RegisterWindowMessage("JumpListProjectClicked");
if (_wmJLPC == 0)
{
throw new Exception(string.Format("Error registering window message: \"{0}\"", Marshal.GetLastWin32Error().ToString()));
}
bool onlyInstance = false;
Mutex mutex = new Mutex(true, "b73fd756-ac15-49c4-8a9a-45e1c2488599_ProjectTracker", out onlyInstance);
if (!onlyInstance) {
ProcessArguments();
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
GC.KeepAlive(mutex);
}
internal static void ProcessArguments()
{
if (Environment.GetCommandLineArgs().Length > 1)
{
IntPtr param = Marshal.StringToHGlobalAuto(Environment.GetCommandLineArgs()[1]);
PostMessage(HWND_BROADCAST, _wmJLPC, IntPtr.Zero, param);
}
}
}
其他地方,在我的表...
protected override void WndProc(ref Message m)
{
try
{
if (m.Msg == _wmJLPC)
{
// always returns an empty string
string param = Marshal.PtrToStringAnsi(m.LParam);
// UI code omitted
}
}
catch (Exception ex)
{
HandleException(ex);
}
base.WndProc(ref m);
}