Search code examples
c#compact-frameworkwindows-ce

Current form's UI freezes while creating a process to initialize cab installer


I have a form that starts a process to initialize cab installation. When the process is created and running, my current UI freezes (I have a loading icon running using a thread timer).

//When the form initializes, the following timer is created to start the animation
System.Threading.TimerCallback TimerDelegate = new System.Threading.TimerCallback(animationTimer);
timer = new System.Threading.Timer(TimerDelegate, null, 0, 100);

//After i started the following snippet to create a process to start cab installation, the animation freezes in my current Form
ProcessInfo pi = new ProcessInfo();
byte[] si = new byte[128];
string szImageName = "\\Windows\\wceload.exe";
string destPath = swPath;
string szCmdLine = @"/noaskdest /noui " + (char)34 + destPath + (char)34;
bool result = CreateProcess(szImageName, szCmdLine, IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, IntPtr.Zero, si, pi);
System.Threading.Thread.Sleep(100);
if (result == true)
{
       int waitResult = 0;
       waitResult = WaitForSingleObject(pi.hProcess, INFINITE);
       CloseHandle(pi.hThread);
       CloseHandle(pi.hProcess);

       label1.Text = "Update is complete. Rebooting device...";
       label1.Refresh();
       System.Threading.Thread.Sleep(1000);
       SetSystemPowerState(IntPtr.Zero, 0x00800000, 0x00001000);

}

How can i ensure the animation on my current form continue to run, while at the same time the created process is running? Please advice, thanks.


Solution

  • Depending on how the Timer is implemented, it may be blocked. This is the case if the timer uses WM_TIMER messages internally. These message have to be processed by a message handler, but when the message pump is not available, as when the code blocks, the timer will not be executed.

    You need to start your Process and the WaitForSingleObject call in a separate thread. So the WaitFor does not block your UI code (with the message pump).

    You may implement a delegate and event handler, so the thread can update the UI. Then in the WaitForSingleObject do not use INFINITE but a TimeOut value and then in a case switch check for the wait result. If it is WAIT_TIMEOUT, you can use this to update the UI (using a event handler).

    You may use this as a starting point for threading and GUI updates. But there are also other good sources on how to do that.