Подтвердить что ты не робот

Привести другие процессы Окно на передний план, если у него есть ShowInTaskbar = false

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

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

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

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

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

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

4b9b3361

Ответ 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 использует имя выбранного каталога как заголовок окна (хотя и невидимый). Теперь, если заголовок окна является общим термином или совпадает с именем каталога приложения, это может быть проблемой.