Перевести другое окно процессов на передний план, когда оно имеет ShowInTaskbar = false - PullRequest
37 голосов
/ 14 апреля 2010

Мы хотим, чтобы одновременно работал только один экземпляр нашего приложения. Таким образом, при запуске он проверяет, запущено ли приложение, и если это так, вызывает в главном окне SetForegroundWindow .

Это все хорошо и хорошо ... по большей части ..

Когда наше приложение запустится, оно покажет экран-заставку и форму входа. Обе эти формы имеют ShowInTaskBar = false .

Из-за этого, если вы попытаетесь запустить другую копию приложения, когда отображается форма входа в систему, эта форма входа в систему не выводится на передний план !

Тем более, что пользователь не видит ничего и на панели задач, все, что они считают, это то, что приложение не работает и не может запуститься. Нет никаких признаков того, что запущен другой экземпляр.

Есть ли способ обойти эту проблему?

Ответы [ 3 ]

48 голосов
/ 14 апреля 2010

Ну, код здесь. Даже если 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 на заставке. Я думаю, что это то, что вы хотите сделать - вывести заставку впереди во время загрузки основной формы.

27 голосов
/ 09 июня 2016

Я думаю, что это лучшее решение, потому что оно восстанавливается из минимизированного состояния:

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);
0 голосов
/ 08 апреля 2013
FindWindow(null, title);

Найдет первое окно, соответствующее запросу. Это может привести к неожиданному поведению, если другое окно использует тот же заголовок.

Хотя шансы на то, что это произойдет, могут показаться редкими или невозможными (одно приложение), это может легко произойти. Например, проводник Windows использует имя выбранного каталога в качестве заголовка окна (хотя оно и невидимо). Теперь, если заголовок окна является общим термином или совпадает с именем каталога приложения, это может быть проблемой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...