MoveWindow не работает на некоторых машинах для процесса chrome - PullRequest
0 голосов
/ 21 апреля 2020

В моем приложении C# я пытаюсь открыть браузер chrome и переместить его на второй экран. Когда я запускаю его на своем локальном компьютере в Visual Studio, он работает правильно большую часть времени. Я также попытался запустить его на другом внешнем компьютере (запустив файл .exe), и это сработало, но на каком-то третьем внешнем компьютере он не перемещает процесс chrome правильно на второй экран.

Вот код:

//before this I programmatically close all chrome processes to be sure there are no active chrome processes

Process process = new Process();
process.StartInfo.FileName = "chrome";
process.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
var testUrl = ... // some url

process.StartInfo.Arguments = testUrl + " --new-window --incognito --start-fullscreen";
var contentScreen = allScreens.Where(screen => screen.Bounds != ScreenHandlingExtensions.MyApp.Bounds).FirstOrDefault(); 

//ScreenHandlingExtensions.MyApp is my main app, I want to start my main app on one screen and chrome browser on another

try
{
      process.Start();
      while (!process.HasExited)
      {
           IntPtr handleId = process.MainWindowHandle;
           if (handleId.ToInt32() != 0)
           {            
                var result = MoveWindow(handleId,
                                 Convert.ToInt32(contentScreen.WorkingArea.X),
                                 Convert.ToInt32(contentScreen.WorkingArea.Y),
                                 Convert.ToInt32(contentScreen.WorkingArea.Width),
                                 Convert.ToInt32(contentScreen.WorkingArea.Height),
                                 true);

                Thread.Sleep(500);

                if (result == true)
                {                          
                    break;
                }
           }   
}
catch
{
      process.Dispose();
}        


[DllImport("user32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

Как я уже сказал, этот код корректно работал на 2 из 3 машин. На 3-й машине я обнаружил, что свойство handleId было неправильным (это было не 0, а просто неправильное значение, я думаю), и именно поэтому MoveWindow не перемещало его правильно (даже если result значение из MoveWindow API был true).

Я нашел решение, чтобы оно работало на 3-й машине, поставив Thread.Sleep(10000) после строки process.Start(), но я не думаю, что это симпатичное решение и не уверен, будет ли оно работать постоянно ,

Я перепробовал множество решений, которые не работали с process.Refresh, одно из них ниже:

while (string.IsNullOrEmpty(process.MainWindowTitle))
{
      System.Threading.Thread.Sleep(100);
      process.Refresh();
}

Также пробовал решение с другой страницы Stackoverflow: Как перечислить все windows принадлежащие определенному процессу, использующему. NET? , который не устранил проблему.

Единственное, что исправило проблему, было Thread.Sleep в течение 10 секунд (5 секунд не работали ), знаете ли вы, в чем заключается реальная проблема и что является лучшим решением здесь?

Редактировать:

Также, если я уберу break из условия, если result == true будет двигаться chrome браузер на другой экран правильно, но тогда я буду иметь, пока l oop работает все время.

1 Ответ

0 голосов
/ 21 апреля 2020
    public IntPtr GetMainWindowHandle(Process process)
    {

        IntPtr handle;

        do
        {

            handle = process.MainWindowHandle;

            Thread.Sleep(333);

        } while (handle == IntPtr.Zero);

        return handle;

    }

Это просто базовая c проверка нулевого указателя, которая может сработать, потому что вы не можете заранее определить, сколько времени потребуется окну, чтобы получить дескриптор и отобразиться.

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