Привести другие процессы Окно на передний план, если у него есть ShowInTaskbar = false
Мы хотим, чтобы один экземпляр нашего приложения запускался в любой момент времени. Поэтому при запуске он смотрит, работает ли приложение, и если это так, он вызывает SetForegroundWindow в главном окне.
Это все хорошо и хорошо... по большей части..
Когда наше приложение запустится, вы увидите экран Splash и форму входа в систему. Обе эти формы имеют ShowInTaskBar = false.
Из-за этого, если вы попытаетесь запустить еще одну копию приложения, когда отображается форма входа в систему, эта форма входа не выводится на передний план!
В частности, поскольку пользователь не видит ничего на панели задач, все, что они делают, - это приложение, которое не работает и не может запускаться. Нет никаких указаний на то, что работает другой экземпляр.
Есть ли способ решить эту проблему?
Ответы
Ответ 1
Ну, код здесь. Даже если ShowInTaskBar
false
, вы можете перенести его на передний план.
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
public static void bringToFront(string title) {
// Get a handle to the Calculator application.
IntPtr handle = FindWindow(null, title);
// Verify that Calculator is a running process.
if (handle == IntPtr.Zero) {
return;
}
// Make Calculator the foreground application
SetForegroundWindow(handle);
}
Примечание: вы должны FindWindow
использовать класс формы, а не по имени, поскольку формы заставки иногда не имеют заголовков или даже панели управления. Используйте Spy ++, чтобы копать глубже.
Используйте FindWindow
для всплеска. Я думаю, что это то, что вы хотите сделать - принесите экран заставки спереди при загрузке основной формы.
Ответ 2
Я думаю, что это лучшее решение, потому что его восстанавливает из минимизированного состояния:
public static class WindowHelper
{
public static void BringProcessToFront(Process process)
{
IntPtr handle = process.MainWindowHandle;
if (IsIconic(handle))
{
ShowWindow(handle, SW_RESTORE);
}
SetForegroundWindow(handle);
}
const int SW_RESTORE = 9;
[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr handle);
[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern bool ShowWindow(IntPtr handle, int nCmdShow);
[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern bool IsIconic(IntPtr handle);
}
Простой вызов:
WindowHelper.BringProcessToFront(process);
Ответ 3
FindWindow(null, title);
Будет найдено первое окно, соответствующее запросу. Это может привести к неожиданному поведению, если другое окно использует тот же заголовок.
Хотя шансы на это могут показаться редкими или невозможными (приложение с одним экземпляром), это может легко произойти. Например, проводник Windows использует имя выбранного каталога как заголовок окна (хотя и невидимый). Теперь, если заголовок окна является общим термином или совпадает с именем каталога приложения, это может быть проблемой.