Запустить приложение и отправить его на второй монитор?

Есть ли способ запустить / запустить программу через Process на другом экране?

Кто-то спросил это здесь, но ответа не было.

Примечание: это не форма в моем приложении, я спрашиваю о запуске внешней программы на другом экране!

5 ответов

Решение

Так как окно не ваше, вы можете переместить его, вызвав Windows API. Вам придется сделать это:

  • Запустите процесс.

  • использование FindWindow вернуть ручку к окну. Если окно еще не существует, процесс еще не создал его; спать на 500 мс, а затем повторите попытку. (Но не входите в бесконечный цикл; остановитесь, если вы не можете найти окно после разумного времени ожидания.)

  • использование SetWindowPos изменить положение окна.

Если вы не знаете заголовок окна, вы не можете использовать FindWindow, В таком случае,

  • Запустите процесс и получите дескриптор процесса, получив Process.Handle,

  • использование EnumWindows чтобы восстановить все окна. Для каждого окна используйте GetWindowThreadProcessId чтобы проверить, принадлежит ли он вашему процессу. Если ни одно окно не принадлежит вашему процессу, подождите и продолжайте попытки.

  • использование SetWindowPos изменить положение окна.

Конечно, вы можете использовать Screen.AllScreens[n].WorkingArea чтобы получить положение и размер экрана, который вы хотите, а затем вы можете расположить окно относительно этого.

Сначала выйдите из области второго монитора, используя что-то вроде:

Rectangle area = Screen.AllScreens[1].WorkingArea;

Используйте Windows API SetWindowPos для его перемещения, используя Process.MainWindowHandle, который вы получили от запуска другого процесса в качестве дескриптора.

Timwi предоставил очень полезный совет, поэтому я решил создать скрипт powershell, вызывающий библиотеку с этими функциями для более легкого использования, и поделиться решением.

Мне нужно было запустить несколько окон Chrome при запуске, и решение на GitHub предназначено именно для этой проблемы (связанный вопрос: /questions/12899979/gde-ispolzuyutsya-osobyie-chisla-upomyanutyie-v-matematike-betona/12900004#12900004).

Но основная логика та же:

  1. Найти дескриптор Windows для работы с. Вы можете использовать Find Window или EnumWindows в общем случае, как упомянул Тимви. Но если ваш процесс прост и имеет одно главное окно, это просто:

    var hndl = proc.MainWindowHandle
    
  2. Имея ручку, вы можете использовать следующую функцию. Вам просто нужно указать номер дисплея (начиная с 1) и дескриптор:

    public static bool MoveToMonitor(IntPtr windowHandle, int monitor)
    {
        monitor = monitor - 1;
        return WinApi.SetWindowPos(windowHandle, IntPtr.Zero, Screen.AllScreens[monitor].WorkingArea.Left,
            Screen.AllScreens[monitor].WorkingArea.Top, 1000, 800, SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOREDRAW);
    }
    

Все перечисления и импорт функций вы можете найти на http://www.pinvoke.net/ или просто скопировать мой код на GitHub: https://github.com/alex-tomin/Tomin.Tools.KioskMode.

Вам нужно будет запустить процесс, получить главное окно процессов и использовать вызов API, такой как SetWindowPos(), чтобы переместить окно на нужный вам экран.

Если вы не развернули окно до максимума, но не развернули его, когда вы закрываете его, при следующем открытии приложения оно появится на мониторе, на котором оно было в последний раз.

Если приложение / окно развернуто, когда вы его закрываете, и если вы откроете его снова в следующий раз, оно появится на вашем основном мониторе.

Попробуйте поместить этот код в form_load метод:

this.setdesktoplocation(int x, int y);
this.windowstate = formwindowstate.maximized;

Значение x должно быть больше ширины вашего основного экрана. Например, если ваш главный экран имеет разрешение 1366 на 786 пикселей, вы должны задать значение xa по крайней мере 1368 или выше.

Это сработало для меня. Но это только для целей отладки. В конце концов, вам придется запустить его на главном мониторе, когда приложение будет завершено.

Другие вопросы по тегам