Я пытаюсь вызвать скрытое приложение при попытке повторно открыть приложение. Оно работает, когда оно находится в свернутом состоянии, но не работает, когда окно находится в скрытом состоянии!
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
namespace Adan
{
public partial class App : System.Windows.Application
{
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
static extern bool IsIconic(IntPtr hWnd);
const int SW_RESTORE = 9;
const int SW_SHOW = 5;
private static Mutex mutex;
protected override void OnStartup(StartupEventArgs e)
{
bool createdNew;
mutex = new Mutex(true, "AdanMutex", out createdNew);
if (!createdNew)
{
IntPtr handle = FindWindow(null, "أذان ليبيا");
if (handle != IntPtr.Zero)
{
// Check if the window is iconic (minimized)
if (IsIconic(handle))
{
ShowWindow(handle, SW_RESTORE);
}
else
{
// If window is not visible, show it
if (!IsWindowVisible(handle))
{
ShowWindow(handle, SW_SHOW);
}
}
// Bring the window to the foreground
SetForegroundWindow(handle);
}
else
{
ShowAlreadyRunningMessage();
}
Shutdown();
return;
}
base.OnStartup(e);
}
private void ShowAlreadyRunningMessage()
{
Border border = new Border
{
Width = 300,
Height = 100,
CornerRadius = new CornerRadius(20),
Background = System.Windows.Media.Brushes.White,
Child = new TextBlock
{
Text = "البرنامج يعمل بالفعل",
FontSize = 16,
HorizontalAlignment = System.Windows.HorizontalAlignment.Center,
VerticalAlignment = System.Windows.VerticalAlignment.Center
}
};
Window messageWindow = new Window
{
Width = 300,
Height = 100,
WindowStartupLocation = WindowStartupLocation.CenterScreen,
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
Background = System.Windows.Media.Brushes.Transparent,
Content = border
};
messageWindow.Show();
DispatcherTimer timer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(20)
};
timer.Tick += (sender, args) =>
{
timer.Stop();
messageWindow.Close();
};
timer.Start();
}
protected override void OnExit(ExitEventArgs e)
{
if (mutex != null)
{
if (mutex.WaitOne(0))
{
mutex.ReleaseMutex();
}
mutex.Dispose();
}
base.OnExit(e);
}
}
}
Итак, я попробовал все, но не получилось активировать или открыть скрытое приложение
Есть ли у кого-нибудь решение моей проблемы или полная библиотека для единого экземпляра, подобная той, которая доступна в .NET8?
@RobertHarvey да, приложение работает, но я скрываю, как и большинство приложений, работает в фоновых процессах и в notifyIcon, но при попытке повторно открыть приложение из exe-файла оно должно сделать его активным. То же самое приложение не то, что скрыто, а не дублировано.
У вас правильная идея с мьютексом, но там есть вещи, которые вам, похоже, не нужны, например таймер. Кажется, ваша основная проблема заключается в том, что вы взаимодействуете со вторым экземпляром своей программы, а не с первым.
Попробуйте что-нибудь вроде этого. Он использует System.Diagnostics.Process
для связи с первым экземпляром:
using System.Diagnostics;
protected override void OnStartup(StartupEventArgs e)
{
bool createdNew;
mutex = new Mutex(true, "AdanMutex", out createdNew);
if (!createdNew)
{
NotifyExistingInstance();
Environment.Exit(0);
}
base.OnStartup(e);
}
private void NotifyExistingInstance()
{
var existingAppProcess = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
foreach (var process in existingAppProcess)
{
if (process.Id != Process.GetCurrentProcess().Id)
{
var hWnd = process.MainWindowHandle;
if (hWnd != IntPtr.Zero)
{
ShowWindow(hWnd, SW_RESTORE);
SetForegroundWindow(hWnd);
}
break;
}
}
}
Если это по-прежнему не работает, примените свои обычные навыки устранения неполадок, например, зарегистрируйте точки входа и выхода этих методов, чтобы убедиться, что они действительно выполняются.
Спасибо, но этот метод не сработал, он не показывал скрытое окно, работает только со свернутым окном, но я решил проблему, и он работает хорошо и быстро в окне восстановления приложения.
Наконец нашел решение, и оно работает нормально
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
namespace Adan
{
// Partial application class in WPF
public partial class App : System.Windows.Application
{
// Unique event name to avoid duplicate runs
private const string UniqueEventName = "AdanAppEvent";
// Unique Mutex name to ensure a single instance of the application
private const string UniqueMutexName = "AdanAppMutex";
private static Mutex _mutex = null;
private static EventWaitHandle _eventWaitHandle;
// Importing the SetForegroundWindow function from the user32.dll library
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
// Method called on startup
protected override void OnStartup(StartupEventArgs e)
{
bool createdNew;
_mutex = new Mutex(true, UniqueMutexName, out createdNew);
_eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, UniqueEventName);
if (createdNew)
{
base.OnStartup(e);
Thread listenerThread = new Thread(ListenForShowWindowEvents);
listenerThread.SetApartmentState(ApartmentState.STA);
listenerThread.IsBackground = true;
listenerThread.Start();
}
else
{
_eventWaitHandle.Set();
Process current = Process.GetCurrentProcess();
foreach (Process process in Process.GetProcessesByName(current.ProcessName))
{
if (process.Id != current.Id)
{
SetForegroundWindow(process.MainWindowHandle);
break;
}
}
// Clean exit ensuring resources are freed
Environment.Exit(0);
}
}
protected override void OnExit(ExitEventArgs e)
{
if (_mutex != null)
{
_mutex.ReleaseMutex();
_mutex.Dispose();
}
// Ensure other resources are freed, if any
base.OnExit(e);
}
// Thread listening for window show events
private void ListenForShowWindowEvents()
{
while (true)
{
_eventWaitHandle.WaitOne();
System.Windows.Application.Current.Dispatcher.Invoke(() =>
{
if (MainWindow != null)
{
if (MainWindow.WindowState == WindowState.Minimized)
{
MainWindow.WindowState = WindowState.Normal;
}
MainWindow.Activate();
MainWindow.Topmost = true; // Temporarily bring the window to the foreground
MainWindow.Topmost = false; // Then set it back to false
MainWindow.Show();
}
});
}
}
}
}
Я не понимаю. Ваше приложение запущено, но главное окно скрыто, и вы хотите его показать?