I have a Windows Form app, that uses Forms.WebBrowser. Due a known issue of WebBrowser, there is an incremental memory leak during time. Following previous advices about this issue, i choosed to restart the app, using cmd. But i noticed that even if i launch the app minimized, my current ActiveWindow lose the focus: i.e. if i'm writing on a .txt file, when the app it's launched as minimized, i lost focus on the file .txt and i'm forced to stop writing.
Here the code i use.
Dim info As New ProcessStartInfo
With info
.Arguments = "/c " + Chr(34) + Application.ExecutablePath + Chr(34)
.WindowsStyle = ProcessWindowsStyle.Hidden
.CreateNoWindow = True
.FileName = "cmd.exe"
End With
Process.Start(info)
Application.Exit()
I would like to launch the application throught cmd, without loose my current active windows focus on another program i'm using. I suppose could be a cmd argument. Any help?
Update:
After some searches:
https://www.codeproject.com/Questions/170180/How-to-find-out-which-is-the-active-current-window
How to bring a window foreground using c#?
i've found a solution calling Windows API:
i made some test and using the Windows Api i can get the previous process with Active Window, and give back the focus to that process, after the re-launch of my app, leave it the focus.
But i reached to do it, waiting a delay (in ms).
I would like to restore the focus when the app it's launched, but here should be the issue: appear to me that even if i launch the app minimized, when the app it's settled on the TaskBar (NB not when the process is running), windows OS give the focus to the taskbar, and if i'm writing, i.e. in a .txt, i loose the focus while i'm writing.
i'm doing:
- Launch my app
- Do what i want (minimize, ...move on desktop, ...put the app in background using another app...)
- before i re-launch the app, i store the current state of the app (i.e. minimized, ...location)
- call Windows API for check the which is the process that is currently running as active Window, and store this process.
- call cmd to re-launch my app, with stored parameters
- wait (NB HERE IS MY PROBLEM: i can wait some seconds, but i would like to wait until re-launched app is present in TaskBar)
- just after the re-launched app is present in taskBak, i use Windows API to restore focus in previous active Window process.
- End my app (while my re-launched app is running)
here the code:
Private Declare Function GetForegroundWindow Lib "user32.dll" () As Integer
Private Declare Function GetLastActivePopup Lib "user32.dll" (hwnd As IntPtr) As Integer
Private Declare Function SetForegroundWindow Lib "user32.dll" (hwnd As IntPtr) As Integer
Private Declare Function SendMessageW Lib "user32.dll" (hwnd As IntPtr, msg As Integer, wParam As Int32, lParam As Int32) As Boolean
Private Shared WM_SYSCOMMAND As Integer = 274 'select an item from the Window menu
Private Shared SC_RESTORE As Int32 = 6172 'restore the Window
And:
Private Sub Restart()
'' Get current Active Window
Dim fw As IntPtr = GetForegroundWindow
Dim lap As IntPtr = GetLastActivePopup(fw)
Dim activeWindowsProcess As Process = Nothing
Dim AllProcess() As Process = Process.GetProcesses
For Each proc As Process In AllProcess
If proc.MainWindowHandle = lap Then
activeWindowsProcess = proc
End If
Next
'' Set re-launched app
Dim info As New ProcessStartInfo
With info
.Arguments = "/c " + Chr(34) + Application.ExecutablePath + Chr(34)
If Not Me.Handle = GetForegroundWindow OrElse Me.WindowState = FormWindowState.Minimized Then
.Arguments += " m"
Else
.Arguments += " " + Me.Location.X.ToString + " " + Me.Location.Y.ToString
End If
.WindowsStyle = ProcessWindowsStyle.Hidden
.CreateNoWindow = True
.FileName = "cmd.exe"
End With
Process.Start(info)
'' loop waiting ...seconds
Dim Delay As Date = Date.Now.AddMilliseconds(500)
While Delay > Date.Now
Application.DoEvents()
End While
'' loop waiting process its launched: NOT WORKING
Dim AllMyProcess As Integer
Dim myappname As String = System.Reflection.Assembly.GetExecutingAssembly().GetName.Name
Dim myVSappname As String = myappname + ".vshost"
Do
For Each proc As Process In Process.GetProcesses
If proc.ProcessName = myappname OrElse proc.ProcessName = myfullappname Then
AllMyProcess += 1
End If
Next
Loop While AllMyProcess < 2
'' call back focus on Active Window
If Not IsNothing(activeWindowsProcess) Then
SetForegroundWindow(activeWindowsProcess.MainWindowHandle)
SendMessageW(activeWindowsProcess.MainWindowHandle, WM_SYSCOMMAND, SC_RESTORE, 0)
Else
SetForegroundWindow(lap)
SendMessageW(lap, WM_SYSCOMMAND, SC_RESTORE, 0)
End If
'' Close app
Application.Exit()
End Sub
My problem now should be to call Windows API to TaskBar, checking until there will be 2 of my app launched.
Does someone know if this is a good code for my pourposes?
And if yes, how to Call Windows API to TaskBar for check current programs?
Thank you.