I got a bit of a problem.
Related to my earlier questions about Slipstreamed SP3 vs. patched SP3, we've come to the conclusion that there is an Internet Explorer process being started, instructed to load a simple .html file from the local disk, which contains javascript, which opens up the rest of a larger chat/meeting system. Internet Explorer is started from a Lotus Notes client.
Unfortunately, all we can see is the IExplore.exe process popping up in Task Manager, and some seconds later, disappear again.
If we try to open the local .html file, which we've found on disk, it gives us that information bar at the top, telling us that it has disabled active content. This, however, is not the real problem. We have another machine that has the same settings but where everything works, and loading the .html file manually gives us the same error there as well.
However, perhaps there is another error message being shown when IExplore is started from notes, but since this process is supposed to just kickstart the rest of the system, and this window is hidden, we can't see it, that is, the error message / problem.
So, I thought, perhaps I should try creating a small program that waits for IExplore.exe to start, then immediately shows the window, so that we can see the error message, or whatever the problem is. At least, hopefully we'll be able to see that.
So far so good, except that if I start a process from my own program, with a hidden window, the main window handle is 0, and thus I cannot show the window after all. I expect this IExplore.exe process started from Lotus Notes to have the same issue.
My monitoring program is written in C#, and basically runs this loop:
foreach (var process in Process.GetProcesses())
{
if (process.ProcessName.ToLower() == "iexplore")
result.Add(process);
}
This picks up all the IExplore.exe processes, windows or not, and with IE8, I get 2 processes for the first window, as expected. I run this over and over again, and handles the differences from the previous runs.
However, the process briefly has a window handle 0 at the start, so I changed it to this:
foreach (var process in Process.GetProcesses())
{
if (process.ProcessName.ToLower() == "iexplore" &&
process.MainWindowHandle != IntPtr.Zero)
{
result.Add(process);
}
}
but now it doesn't pick up anything at all, even after the window has gotten a handle (and yes, process.MainWindowHandle does have a non-zero handle value after the window has been shown, but in the case where the window is never shown, it stays at 0.)
So, the question is: Is there any way for me to take this hidden IExplore.exe process, and instruct it to show itself, when it doesn't have a window handle already? I doubt it, but perhaps someone can prove me wrong.
If not, my backup plan is to create a shim IExplore.exe program, that forwards all command line arguments to the original one, except that it specifies that the window is to be shown. Would this be a solution?
I do not believe there is any way to force an IE window which does not have a window handle to allocate a window handle for itself (or use a previously allocated one) and display itself.
As to your backup method: I think this would work, but you're working in dangerous territory there. I'd actually recommend writing your shim to just log every invocation of iexplore.exe and everything that goes into it, and use that to characterize your problem; only after thoroughly characterizing your problem with completely benign logging would I suggest possibly modifying the parameters to force iexplore.exe to display a window.
Related
I'm new to c#. Antivirus deleted the mySolutionName.exe file out of the /debug directory and now I cannot execute my code. I'm concerned that anything I do may make the issue worse.
When I press F5 I get an error of:
CS2012 C# Cannot open for writing --> C:\Users\me\source\repos\MyApp\MyApp\obj\Debug\MyApp.exe''
Can someone please tell me how to rebuild the file so that I can continue developing?
after your edit:
Your program is probably still running outside of the debugger.
You need to use the task-manageer to kill all instances of MyApp.exe if this doesnt solve your issue a reboot should do the trick as well
So why is this happening?
Most liky your application is somewhere stuck on a blocking function or in a never ending loop. maybe there is even a seperate thread still operating that you forgot to close. We lack some information to tell yout that for sure. But to find out what is happening you can close your window while running in debugger mode and see if the application properly closes. if it doesnt you can hit pause and see where the program is stuck and resolve this issue by ending the task/loop/whatever in your OnClosing function of your window.
A good way to solve this issue is looking which process currently accesses the file.
A tool to do that is Microsoft SysInternals Process Explorer. It has a feature called "Find handle or DLL ..." which can be accessed by Ctrl+F.
The result will show the process which accesses the file. You can then judge whether it's Antivirus or something else that prevents you from writing to the file. If possible, you can then take an action in that program to release the file.
Example: a program is accessing my powerpoint presentation, which has the term "Schulungen" in its file name.
Process Explorer figures out: it's open in Powerpoint.exe, so I can simply close the file in Powerpoint - problem fixed.
I know Windows Store Apps are executed in isolated mode (a sandbox). Hence I start an App (e.g. Microsoft Photos) by using IApplicationActivationManager.ActivateForFile, the image provided gets displayed and the return value of the function gives me the process Id (e.g. 6544 for a process named ‘ApplicationFrameHost’ and a main window title of ‘Photos’. But when I register a handler to the .Exited() event of the according process I won’t get informed when I close the App (unlike to a Win32/64 application like notepad.exe).
Unpleasantly furthermore I receive the same Process Id for the next image to be displayed as well – both images are held by the same process now. And all images displayed subsequently return the very same process Id as well... and my .Exited-Handler is still not called, neither in case I close only one of now several running Photo-Apps nor after finally I have closed all of them.
Since I could not yield notification about the process with my image was closed I thought of looking up if it is still on display. I investigated all propertied of Process including the ProcessThreadCollection and ProcessStartInfo but found nothing to identify my displayed images. And even when I investigate the MainWindowsTitles by looping through the open windows (with User32.EnumWindows() or WindowsInterop.GetRootWindowsOfProcess(p.Id) this does not give me more then fife times “Photos” for fife displayed images – alas without the filenames of the images displayed!
Any hint to get around that would be greatly appreciated!
You can use AppDiagnosticInfoWatcher to monitor the state of an app and get notifications when it changes:
https://learn.microsoft.com/en-us/uwp/api/windows.system.appdiagnosticinfowatcher
I am looking for a way to run selenium tests with a chrome driver, in the background. With the background I mean as in, not the foreground focussed window. I can actually do this, but as soon as actions like opening a new tab or switching between windows (so basically switching window handles) happen in the chrome driver, the browser window gets pushed to the foreground.
So my question is, how can I prevent this from happening without running the test headless?
Any suggestions are appreciated, open for discussion.
EDIT
As a somewhat temporary solution I came up with the following.
Using the Windows 10 Virtual Desktops feature, I run the test and thus the chrome browser window in a seperate virual desktop.
I then switch back to my main virtual desktop to continue with other tasks.
This prevents the chrome browser window from being forced to the foreground.
Note that this still makes a flashing chrome icon appear in the taskbar when any of the actions described above appear.
Still looking for a more solid solution, so any suggestions are still appreaciated.
To hopefully open new perspectives and discussion points, and ultimately a solution, I will provide some more detailed info of what my code is doing.
I have 5 chrome webdrivers, and each of these webdrivers contains 6 tabs (WindowHandles).
The idea is that a certain process has to be repeated continuously on each tab. So we loop over each webdriver, and within that webdriver over each tab and set this tab as the webdrivers current WindowHandle. This makes the chrome window visibly switch to the assigned tab.
After that switch has taken place, so basic selenium automation is performed on the content of the tab, after wich we repeat the whole process.
The actual issue seems to take place when a chrome webdriver switches to a new tab (WindowHandle), at this moment the chrome window containing the tab is pushed to the foreground and steals focus. Note that this does not always takes place, often it can switch tabs without any issues. So it is unclear wether there is another factor which would cause the window to steal focus.
EDIT 2
After doing the following:
I overloaded the selenium method which is used to switch between tabs (WindowHandles), and called SetWindoPos each time. Unfortunately this did not solve this issue either. I will try to look deeper into what might be causing this and will report back. – S. Van den Wyngaert
I went out for a few hours while running the tests, and came back to see that surprisingly I was still on my main Virtual Desktop (win10 feature). This means that the issue didn't occur during the time I was gone. I started working again, opened a chrome window and noticed that shortly after I did this, focus was stolen by one of the chrome driver's windows again.
What I conclude from this is that the issue only occurs when another chrome window (not opened by a chrome driver from code) is opened.
I will keep investigating and will report back with updates.
After investigating this behavior for a few more hours I noticed that when another chrome window is open, as long as this has focus, the issue doesn't take place. So to quickly summarize this:
The issue doesn't take place when:
No other chrome windows (not selenium driven) are opened or minimised
Another chrome window (not selenium driven) is opened and has focus
Another application running fullscreen mode has focus
The issue does take place when:
Another chrome window (not selenium driven) is opened and has no focus
Note that when I talk about another chrome window I specificly mean a chrome window that is not driven by selenium, so a regular chrome window opened by the user.
Easiest way would be to run a local selenium grid. Start your node(s) as a windows service. This way the test will run in the background, without being headless.
Another good option to scale your solution, and if your machine has the capacity to run docker, is to use
zalenium
It's a docker based, auto scaling, selenium-grid solution that works pretty quick out of the box.
You can watch your tests live via the management pages, watch a recording after the fact, pause/debug with live interaction via VNC. Also something to be said for not having the worry about changing browser versions.
Last time i used it, it had the odd bug and throws an end of stream error every now and then - but that was a good year ago.
I've written a WPF/C#-based "shell" which launches WPF apps or other apps.
What would be the best method for checking if the process is finally fully launched or no longer "busy"? I've noticed that the mouse cursor for the launched process stays at the busy cursor from initial launch until I can finally see the UI for the process. Could I use User32.SetCapture API to set the mouse capture to the external process, then somehow check if the mouse cursor is the busy cursor? Or perhaps there's a mechanism in the System.Diagnostics.Process class that I'm unaware of?
As some of the launched apps are pre-compiled third-party apps, I absolutely cannot implement a mechanism in the external processes to message if it is finally ready, such as: Microsoft PowerPoint 2010 Viewer, Adobe Acrobat, or Adobe Flash Player Standalone.
I can't just check if the process has been created, because then I have a blank, unresponding window and a busy cursor. I hope to hide my WPF app the moment the external process is done launching.
The WaitForInputIdle Win32 APi function will wait until given process enters the message loop (with no input pending).
Quote: "Before trying to communicate with the child process, the parent process can use the WaitForInputIdle function to determine when the child's initialization has been completed."
You can call it via P/Invoke.
Not very cear what do you mean saying "beasy", but hear are several considerations:
There is no known (clear) way, at least that I'm aware of, that can let you do something like that. The thing is that process is perfectly isolated OS kernel citizen. So you can not write something that works for all type processes, especially if they are 3rd part binaries.
What you can try to do, is get the MainWindow of the process (if there is any), get its handle, and filter OS messages untill you get for example WM_ACTIVATED.
But even if this could work in certain situations, in others can measurably fail. For example, process loaded but the program is not active, cause for some reason License window of the application appeared.
Let's see what others suggest, in my opinion, there is no generic and no single solution to cover minority of possible cases.
Good luck
I would like to set up a persistent state for my application. Let me explain.
The startup time is kinda long (mostly due to many database requests to a remote server, which take 5 - 10 seconds, and even more since my users usually have too much applications running...) and I'd like to set up a way to hide & show my application when needed.
What I am doing now is to only reduce app to tray when user clicks on the red cross. (The application really exits only when a user chooses File -> Exit).
All users are launching an installer which is checking the version installed, then the version available online, and update the app if needed before launching it.
Now, I'd like it to first check on the process monitor (the one found in Task Manager, Processes tab), and if a process is already running for the application, it'll just show the window again. Otherwise, if no process is running, we can process the classic-check-for-update-then-launch steps.
This would especially remove a lot of stupid customer requests I regularly have ("hey, your application takes too long to load, so I clicked on it again 5 times and it launched 6 instances!!!!" :/ ) and therefore save me a lot of useless time spent asking them to stop launching 50 instances of the same application cause it won't make it any faster...
So my main question is: how to perform such a trick in C#/WPF?
For now, my minimization process is kinda simple (even though maybe too simple): I just hide the window & the task bar entry. Now I don't know how to show it back from my installer
Any ideas?
Your customers' requests can never be stupid - they pay you money.
To bring window to front - create system wide mutex and check its presence on application startup. If it's there - use interprocess communication mechanisms to send message to that other instance to bring its main window to front (a window message or named pipe - both are fine). Here is an example (make sure to check related answers too).
And by any means show splash screen as soon as you can to prevent relaunching application again and again. If it does not appear in 1-2 seconds (2 is too long) it's bad. Responsiveness of your application makes feeling like it works faster.
Is it something like this you're looking for?
foreach (var p in Process.GetProcesses())
{
if (p.ProcessName.Contains("myProcess"))
{
//process is already running
}
}
Or, with LINQ:
if (Process.GetProcesses().Where(p => p.ProcessName.Contains("myProcess")).Any())
{
//process is already running
}
If the users complain about startup times, maybe consider checking the version on exit, instead of startup.
I have answered a very similar question yesterday. The only bit that's missing there is how to hide and show the window: use Window.Visibility, set it to Visibility.Hidden to hide the window and to Visibility.Visible to show it again.