I have some problem that bother me for few days..
I need to do the following..
start a process (with some arguments), find the window of the process, take a picture of that window, and kill the process
and I need to repeat this operation X times..
I can start the process, using user32: find its main handle, get the window size, so I know the size of the image, set the window position to 0,0, and make it topMost, and than copyFromScreen metod to capture that image.. from 0,0, to size of the window..
So it look like everything is ok, but there is one problem that I can't solve..
when the process is started, I notice that to use the setWindowPos native function, some time should pass so I use Thread.sleep(x seconds), but
that time is different on every system.. and that is the problem.. I must know how long delay to make on every system.. and I can't let big unnecceary delay because the process repeats hundreds of times.. and every millisecond is important,
Please if You have some solution, I will be happy to hear..
the process is opera mobile emulator..
other solution is to use sendMessage, and change the url, instead of starting the process over and over.. and
I will wait once, but that also doesn't work..
using Spy++ I try to find details about the process, like className .. and it says invalid window..
so I probably can't use sendMessage too..
Browsers are not designed for this kind of usage. If you want to reliably know when some browser is ready for rendering a new page and want to grab the result, try something that actually integrates into the rendering engine / core of the browser.
For the complete framework, see http://phantomjs.org/ For own solution - try embedding a browser widget directly in your application instead of interfacing with another process. I'm sure .net has the right controls for it. This way you can hook to the relevant events directly, instead of guessing the right delays.
Related
I have created an Html 5 page that provides important server-side functionality. Unfortunately, it must be run in an Html 5 browser (Chrome, IE9, or Firefox) with a canvas to produce the results I need. It is completely self contained, taking needed parameters through the URL, and is ready to be closed when the OnLoad event is ready to send. So far so good.
The following process needs to be automated (no human eyes or interaction) and will be run from within a web service (not run from within a browser). Ideally, I don't want to waste extra cycles with busy wait, or delay the result by waiting for long time periods simply hoping the process has finished. I need to:
Open a browser (preferably Chrome) with a URL, using C#.
Wait for the page to completely finish loading - ideally receiving a callback of some kind.
Close the browser page when finished, again with C#.
We've tried using IE9. There is C# support to launch IE9, Wait until not Busy, and gracefully Close the browser; however, the page loads resources asynchronously (there is no way around this), and so we get the signal that it is no longer busy during the resource load - instead of when the page has finished. Adding busy wait would consume valuable server-side cpu cycles.
A simple Create Process call would be nice, but would only work if the browser could close itself with some html - but thanks to security measures in the browsers, I can't find a reliable way to use html commands to close a browser that was launched from command-line (I did see you can close tabs spawned from an already opened page - firefox only, but this doesn't help).
Does anyone know how I can accomplish this goal? Again - there is no human involvement in any of the process, no human eyes will ever see the page or interact with it in any way. The page only runs on the server machine, and will never be deployed to a client machine.
I would suggest to use the WebBrowser control to load the HTML. Once you get the data back, use an ObjectForScripting to call a c# method to notify when done.
See http://www.codeproject.com/Tips/130267/Call-a-C-Method-From-JavaScript-Hosted-in-a-WebBro
You dont really have to even show the webbrowser control.
Let me know if you have any questions. Hope it helps!
Automating the browser - thats what Selenium does. I think it will be a good fit for the task, and there's good C# support. It can even run the browser on a remote machine using the Selenium RC server.
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 am working with the Image generation of a browser, but doing so i am taking a snapshot of the browser from the code, in windows form. But if the browser is not loaded in the specific time (suppose 15 seconds) then a blank snapshot occur. Anyone help me with this .
I'm not entirely sure if I understand exactly what you're trying to do, but I'll take a stab at it: It sounds like you're trying to open whatever program is set as the user's default web browser, and then do something like a BitBlt to take a screenshot of it.
However, as you've noticed, it's difficult to just wait a pre-defined interval and hope the browser has completely loaded. Instead, you could try something like WaitForIdleInput after running the process, which will suspend the thread's execution until the process has finished initializing and is idle (waiting for user input). This should allow the browser to finish loading before you proceed with taking the snapshot.
Something like the following code:
//start the web browser
System.Diagnostics.Process proc = System.Diagnostics.Process.Start("iexplore.exe");
//wait for it to completely finish loading
proc.WaitForInputIdle();
//take your screenshot, or whatever
//...
I want to create an alarm app for myself. On certain conditions (i need to poll websites) i want my app to inform me and make it HARD TO MISS. So i can take appropriate action or ignore it if i need to do something else.
I wrote a test app and using a BalloonTip (ShowBalloonTip with notifyIcon) isnt great. One of my previous apps brings the window in front of you and does a MessageBox however that doesnt always work or work well (if i somehow miss it or accidentally forget to click ok no futher messages will occur).
What are your suggestions?
You could also make it a system tray application and change the icon out if there is something which requires attention, a la a messenger application. That may not be "hard to miss" but I am trained (for better or worse) to look down at the icon tray when I see something blinking.
Where I work, we have a TimeTracker application (built in house) with which developers are supposed to log what we worked on and when. I am notorious for not using it. So, I wrote my own (Windows Forms) version for my own use which, every hour opens up and takes over my screen:
It is a frameless dialog which consumes the entire screen.
TopMost = True.
On resize, it sets WindowsState = Normal and resizes to fill the screen.
While it is open, it polls for taskmgr.exe and procexp.exe and kills them if found.
It disables the start menu to prevent cmd.exe commands from the menu in Windows 7.
The only way to close it is to enter a log, only then is the OK button shown!
So far, it's working out well - no one has been able to break it!
My less drastic suggestion would be to have a notification which pops up momentarily above the system tray. After a second or two, fade it out. Keep showing the notification every 30 seconds or so until it is dismissed.
Always-on-top window in the corner of the screen?
You could always set your window to be a top most window, make it full screen, and activate it. It would be very, very hard to miss...
Granted, it would also be very annoying, and not something I'd do to other users...
My "real" suggestion would be to use sound along with standard notification methods if this is going to be used by other people, as that's an easy way to grab attention without necessarily killing their workflow. A modeless window that appears in a corner of the screen, especially if combined with sound and color, can be very effective to grab attention.
The industry has been adopting these ambient orb devices and variations of it when such a hard-to-miss notification is required. It is used for tracking the stock-market and for broken-daily-builds.
http://www.ambientdevices.com/cat/orb/MAN_Ambient%20Orb_3-23-03.pdf
Regards
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.