I've got a WinForms app, where if there is already an instance running & the user tries to spin up another one, I stop it by checking against a Mutex before calling Application.Run(). That part works just fine. What I would like to do is pass a message from the new instance of the app (along with a piece of data in string form) to the existing instance before killing the new process.
I've tried calling PostMessage, and I do receive the message on the running app, but the string I pass along in the lparam is failing (yes, I have checked to make sure I'm passing in a good string to begin with). How can I best do this?
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);
}
}
}
Elsewhere, in my Form...
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);
}