Reputation: 1
I'm trying to bring up the main window when trying to reopen the app, it works when it's in a background or minimized state but it doesn't work when the window is in a hidden state!
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
namespace SingleInstanceTest
{
public partial class Program
{
private static Mutex? _mutex;
[STAThread]
public static void Main()
{
u_mutex = new Mutex(true, GetApplicationMutexName(), out var isNewInstance);
if (isNewInstance)
{
var app = new App();
app.InitializeComponent();
app.Run();
app.Exit += (sender, e) =>
{
_mutex.ReleaseMutex();
_mutex.Dispose();
};
}
else
{
// var handle = NativeMethods.FindWindow(null, "MainWindow");
// if (handle != IntPtr.Zero)
// {
// if (NativeMethods.IsIconic(handle))
// {
// // NativeMethods.SendMessage(handle, NativeMethods.WM_SYSCOMMAND, (IntPtr)NativeMethods.SC_RESTORE, (IntPtr)0);
// NativeMethods.ShowWindowAsync(handle, WindowShowStyle.Restore);
// }
// NativeMethods.SetForegroundWindow(handle);
// }
var firstInstanceProcess = GetFirstInstanceProcess();
if (firstInstanceProcess != null)
{
if (NativeMethods.IsIconic(firstInstanceProcess.MainWindowHandle))
{
// NativeMethods.SendMessage(firstInstanceProcess.MainWindowHandle, NativeMethods.WM_SYSCOMMAND, (IntPtr)NativeMethods.SC_RESTORE, (IntPtr)0);
NativeMethods.ShowWindowAsync(firstInstanceProcess.MainWindowHandle, WindowShowStyle.Restore);
}
NativeMethods.SetForegroundWindow(firstInstanceProcess.MainWindowHandle);
}
}
}
private static string GetApplicationMutexName()
{
return $"Global\\{Assembly.GetExecutingAssembly().GetType().GUID}";
}
private static Process? GetFirstInstanceProcess()
{
var currentProcess = Process.GetCurrentProcess();
var processes = Process.GetProcessesByName(currentProcess.ProcessName);
foreach (var process in processes)
{
if (process.Id != currentProcess.Id)
{
return process;
}
}
return null;
}
}
internal static class NativeMethods
{
public const int WM_SYSCOMMAND = 0x0112;
public const int SC_RESTORE = 0xF120;
[DllImport("user32.dll", SetLastError = true)]
internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ShowWindow(IntPtr hWnd, WindowShowStyle nCmdShow);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsIconic(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ShowWindowAsync(IntPtr hWnd, WindowShowStyle nCmdShow);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindowInternal(IntPtr hWnd);
}
internal enum WindowShowStyle : uint
{
Hide = 0,
ShowNormal = 1,
ShowMinimized = 2,
ShowMaximized = 3,
Maximize = 3,
ShowNormalNoActivate = 4,
Show = 5,
Minimize = 6,
ShowMinNoActivate = 7,
ShowNoActivate = 8,
Restore = 9,
ShowDefault = 10,
ForceMinimized = 11
}
}
Does anyone have a solution to my problem or a complete library for Single Instance like what is available in .NET Framework, as on my test on this application https://github.com/IgrisModz/WPFSingleInstance/tree/master ?
PS: I had tried with SingleInstanceCore as I'm using .NET 6 but couldn't find how to get the desired behavior.
Upvotes: 0
Views: 501
Reputation: 1
I was able to find what I was looking for via this library: https://github.com/novotnyllc/SingleInstanceHelper/tree/master
I also had this sample: https://github.com/gerardo-lijs/SingleInstance-WPF-Sample it worked but didn't really fit my needs
Upvotes: 0