0

In my C# app I am trying to open chrome browser and move it to 2nd screen. When I run it on my local machine in Visual Studio it works correctly most of the time. I also tried to run it on some other external machine (by running .exe file) and it worked, but on some 3rd external machine it is not moving chrome process correctly to 2nd screen.

Here is the code:

//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);

As I said, this code worked correctly on 2 of 3 machines. On 3rd machine I found out that handleId property was not correct (it wasn't 0 but just some incorrect value I guess) and that is why MoveWindow did not move it correctly (even though result value from MoveWindow API was true).

I found a solution to make it work on 3rd machine by putting Thread.Sleep(10000) after process.Start() line but I don't think it is a pretty solution and not sure if it is going to work all the time.

I tried a lot of solutions that did not work with process.Refresh, one of them is bellow:

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

Also tried solution from another Stackoverflow page: How to enumerate all windows belonging to a particular process using .NET? that did not fix the issue.

The only thing that fixed issue was Thread.Sleep for 10 seconds (5 seconds did not work), do you know what is the real issue and what is the best solution here?

Edit:

Also if I remove break from condition if result == true it will move chrome browser to another screen correctly, but then I will have while loop running all the time.

1 Answers1

0
    public IntPtr GetMainWindowHandle(Process process)
    {

        IntPtr handle;

        do
        {

            handle = process.MainWindowHandle;

            Thread.Sleep(333);

        } while (handle == IntPtr.Zero);

        return handle;

    }

This is just a basic null pointer check that might do the trick, because you can't predetermine the time it will take to a window to get a handle and show up.

Y0GA
  • 1
  • 1