How do I kill a particular chrome tab/process - c#

I am writing a windows service that I would like to run as a scheduled task.
On Start I want it to read in the chrome processes and kill any that have a particular url..
I can get the processes using
var list = Process.GetProcessesByName("chrome");
but after that I am stumped..
The MainWindowTitle of each process is "" and the MainWindowHandle is 0 so doesn't help me.
I have read numerous posts related to this and it seems there is no api into chrome so am I wasting my time?
Any help appreciated
J

If you look at spy++ you can see that you can find root windows that do have their Caption set to the html page title. Also a child window is the url bar so if you enum the child windows of all the chrome windows you uld be able to find it.
sho

While it is possible to do this, I wouldn't recommend it. Injecting yourself in to other processes and reading their contents can cause unpleasant behavior and is hard to get completely correct, but if I was going to try this, I would use the UI automation tools provided by MS (http://msdn.microsoft.com/en-us/library/ms747327.aspx), or White (http://teststack.github.io/White/). Those are going to be the best bets.

Related

How to add extension to running remote multilogin webdriver? (Selenium C#)

First I tried to add extension directly from chrome webstore, but problem is alert popup which appears after you click "add to chrome" is not reachable by selenium. After I wanted to try using options.AddExtension, but multilogin profile starts before selenium takes control so this method is useless. I know that I can manually import .crx for every profile but there are thousands of profiles and I need to automate process of installing extensions. I don't know what to do, I heared there's option to reach popup alert in chrome webstore but can't find it. Or maybe there are other ways to install extension after browser started? I'm glad for any help or advice
I have 2 possible scenarios for you, hope that works out since I don't have direct access to this specific need you have because the extensions may differ.
Not using Selenium, you gonna start the chrome process using the class Process and add the flag --load-extension= to load the specific profile/extension that you need. You can see the entire comma here. To sum, you can use this snippet below to load:
chrome --user-data-dir=/tmp/someuniquedirname --load-extension=path/to/extension --no-first-run //Note: some flags may change between versions of chrome, see full documentation
After defining the extension and start chrome, you can now get hold of the process with Selenium by using another flag: --remote-debugging-port=http://localhost:[localporthere]. After that, start the process than tell to Selenium to get hold of that process with the port and do your job.
Another way is to start the process installing the extension manually and in another Thread use some Automation UI (Teststack.White or FlaUI) to click on the popup you have. I can't extend here in the entire code for this solution because it will go to a opinion-based answer, but you can check on FlaUI for that use, and follow that path:
Selenium starts the program, click on the install extension and wait for the popup to show-up;
New Thread;
FlaUI gets hold of the process that you already start;
Using UIElements, click on the "ok" button you need;
FlaUI drops;
Back to the main thread.
If you need any clarifications about the solutions above, just comment and I'll try to help you further.

Is there any way to detect if an external process is running on exclusive fullscreen mode?

spent the whole day looking up for a solution, but I couldn't find it
I'm not talking about borderless windowed fullscreen, but those exclusive fullscreen mode that usually games use
is this possible?
I think you can get list of the process independently from your mode using System.Diagnostics.Process. Than you can just find any process by name or other properties.
UPDATED
So I have tried some solutions, but for now found one that works if process if full-screen right now, not minimized. Pretty much that:
Is there a way to check to see if another program is running full screen
My code Snippet (Runs in loop and checks if the process with specific name is fullsreen)
https://pastebin.com/qwE7ZXVt
Another possible solution based on window into style flags
https://www.reddit.com/r/AutoHotkey/comments/6maqdd/detecting_if_window_in_the_foreground_is/
But I was unable to make it work. You can try to PM folks there.
Also this site was very handy
https://www.pinvoke.net/index.aspx

C# Is there any other way of opening web shortcuts

Im currently using
System.Diagnostics.Process.Start(link);
to open web links on a dropdown menu in a program for work. However, the security suite on the works computers do not allow this to function. I have spoken with IT and they will not relax the security policies on this.
I've had a search and most of the posts suggest the way I have already done it.
We use IE in work.
Is there another way of opening links?
Thanks
You can launch IE directly from Process start with a url as a parameter like:
System.Diagnostics.Process.Start(#"C:\Program Files\Internet Explorer\iexplore.exe", "http://www.stackoverflow.com");
Cheers,
CEC
PS: additional possible solution: BRIBE THE IT DEPARTMENT, good food is often a working solution to IT dept. problems.
Can you use an embedded browser window? If so, embed the browser window into your C# application and open the link in that window. If not, the starting of the process may not help you because the security suite may prevent this as well.
Have you tried using a ProcessStartInfo object with the UseShellExecute property set to false? This may have a chance of circumventing the security restriction.
http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.useshellexecute.aspx

Starting and stopping firefox from c#

When I start
/Applications/Firefox.app/Contents/MacOS/firefox-bin
on MacOSX using Process.Start() using Mono, the id of the process that gets returned does not match the process that firefox ends up running under.
It looks like firefox quickly decides to start another process, and kill the current one.
This makes it difficult to stop firefox, and to detect if it is still running. I've tried starting firefox using the -no-remote flag, to no avail.
Is there a way to start firefox in such a way that it doesn't do this "I'll quickly make a new process for you" dance?
The situation can somewhat be detected by making sure Firefox keeps on running for at least 3 seconds after its start, and when it does not, scan for other firefox processes. However, this technique is shaky at best, as on slow days it might take a bit more than 3 seconds, and then all tests depending on this behaviour fail.
It turns out, that this behaviour only happens when asking firefox to start a specific profile using -P MyProfile. (Which I need to do, as I need to start firefox with specific proxyserver settings) If I start firefox "normally" it does stick to its process.
When using mozilla programmatically / embedding in other apps you should use the provided components:
"The right way" as recommended by mozilla ...
https://developer.mozilla.org/en/XPCOM
"The easy way", general consensus from Mozilla dev guys ...
http://www.iol.ie/~locka/mozilla/control.htm
Need to "execute processes", simply instantiate an instance of the component and talk to that, you should then have everything you need.
However ...
If you really do insist on looking after the actual process for a firefox instance, you may want to call
Process.Start("...\firefox.exe");
Then try this (i believe this works on MAC OS too) ...
C#/mono: get list of child processes on Windows and Linux
The basic idea / thought pattern being that if it is in fact executing another process right away you should be able to find that as would be a "child" process instead of being just one from a list in the "task list" / process manager for the machine.
In case you are ok with the detection of Firefox process itself but don't know when you should start the detection, you can use the Process.Exited event. Don't forget to set EnableRaisingEvents first.
I suggest taking a different approach: list all running processes, find Firefox, get it's process ID and (optional) see if it is the one you started.
I'm not sure if there's a platform-independent way to accomplish this. On Linux, you can call "ps -ef" to list them, on Windows it's called "tasklist".
I don't have a Mac, so I can't be sure, but if it's anything like Linux the firefox 'binary' is actually a shell script which sets up a bunch of required environment variables and checks if firefox is already running (if it is, it will try and add a new tab to the existing instance, as far as I know).
You may be able to capture the new PID within the script, although if you update it do beware of it being overwritten during upgrades.

Prevent Process 'A' from spawning Process 'B' which then shows up on top of what should be the "TopMost" Process 'C'

I have a windows form application which needs to be the TopMost. I've set my form to be the TopMost and my application works as I'd like it to except for in one case.
There is a 3rd party application (referred to as player.exe) that displays SWF movie files on a portion of the screen that popup on top of my application.
Using Process Monitor I determined that player.exe application calls
flash.exe <PositionX> <PositionY> <Width> <Height> <MovieFile>
in my case:
flash.exe 901 96 379 261 somemovie.swf
Since flash.exe is being spawned in a new process after my form has been set to the TopMost it is appearing on top of my application.
First thing I did was make my application minimize the player.exe main application window hoping that this would prevent the Flash from appearing also. But, unfortunately it doesn't... even with the window minimized whenever the flash movie starts it shows up at the pixel location (901,96). I then tried creating a timer to keep setting the form.TopMost property to true every 10ms. This sort of works but you still see a very quick blip of the swf file.
Is there some type of Windows API call which can be used to temporarily prevent player.exe from spawning child processes which are visible? I admit it sounds a little far fetched. But, curious if anyone else has had a similar problem.
Addendum:
This addendum is to provide a reply to some of the suggestions layed out in Mathew's post below.
For the emergency situation described in the comments, I would look at possible solutions along these lines:
1) How does the third party application normally get started and
stopped? Am I permitted to close it
the same way? If it is a service, the
Service Control Manager can stop it.
If it is a regular application,
sending an escape keystroke (with
SendInput() perhaps) or WM_CLOSE
message to its main window may work.
Easiest way to close the app is to CTRL-ALT-DEL, then kill process. -OR-
The proper way is to Hold ESC while clicking the left mouse button... then input your username and password, navigate some menu's to stop the player.
There is no PAUSE command... believe it or not.
I don't think using WM_CLOSE will help since minimizing the application doesn't. Would that kill the process also? If not, how do you reopen it.
2) If I can't close it nicely, am I permitted to kill it? If so,
TerminateProcess() should work.
I can't kill the process for two reasons. 1) Upon relaunch you need to supply username/password credentials... There may be a way to get around this since it doesn't prompt when the machine is rebooted but... 2) Whenever I kill the process in task manager it doesn't die gracefully and asks if you want to send an error report.
3) If I absolutely have to leave the other process running, I would try
to see if I can programmatically
invoke fast user switching to take me
to a different session (in which there
will be no competing topmost windows).
I don't know where in the API to start
with this one. (Peter Ruderman
suggests SwitchDesktop() for this
purpose in his answer.)
I got really excited by this idea... I found this article on CodeProject which provides a lot of the API Wrapper methods. I stopped implementing it because I think that in order for desktop's to work you must have explorer.exe running (which I do not).
EDIT2: On second thought... maybe explorer.exe isn't needed. I'll give it a try and report back.
Edit3: Was unable to get the code in that article working. Will have to put this on hold for a moment.
Answer Summary
As one might have expected, there is no simple answer to this problem. The best solution would be to problematically switch to a different desktop when you need to guarantee nothing will appear over it. I was unable to find a simple C# implementation of desktop switching that worked and I had a looming doubt that I would just be opening a whole new set of worms once it was implemented. Therefore, I decided not to implement the desktop switching. I did find a C++ Implementation that works well. Please post working C# virtual desktop implementations for others.
Setting the TopMost property (or adding the WS_EX_TOPMOST style to a window) does not make it unique in the system. Any number of topmost windows may be created by any number of applications; the only guarantee is that all topmost windows will be drawn 'above' all non-topmost windows. If there are two or more topmost windows, the Z-order still applies. From your description, I suspect that flash.exe is also creating a topmost window.
Aside from periodically forcing your window to the top of the Z-order, I think there is little you can do. Be warned, however, that this approach is dangerous: if two or more windows are simultaneously trying to force themselves to the top of the Z-order, the result will be a flickering mess that the user will likely have to use the task manager to escape.
I recommend that your program not attempt to meddle with other processes on the computer (unless that is its explicit purpose, e.g. a task manager clone). The computer belongs to the user, and he may not value your program more highly than all others.
Addendum:
For the emergency situation described in the comments, I would look at possible solutions along these lines:
How does the third party application normally get started and stopped? Am I permitted to close it the same way? If it is a service, the Service Control Manager can stop it. If it is a regular application, sending an escape keystroke (with SendInput() perhaps) or WM_CLOSE message to its main window may work.
If I can't close it nicely, am I permitted to kill it? If so, TerminateProcess() should work.
If I absolutely have to leave the other process running, I would try to see if I can programmatically invoke fast user switching to take me to a different session (in which there will be no competing topmost windows). I don't know where in the API to start with this one. (Peter Ruderman suggests SwitchDesktop() for this purpose in his answer.)
You can use the Process class to start flash.exe directly - and use an appropriate ProcessStartInfo settings to show the window in a hidden state - or with a WindowStyle of hidden or minimized.
You could also consider using the SetWindowsHookEx API to intercept the process start API calls, and when the process is flash.exe run some code to restore you window to top-most status.
Matthew's answer is excellent, but I suspect you may be asking the wrong question. Why does your application need to be topmost? If you're trying to create a kiosk or some such, then topmost is not the way to go.
Edit: After reading your response to Matthew's comment, I'd suggest creating a new desktop and switching to it before displaying your alert. (See CreateDesktop and SwitchDesktop in MSDN.)

Categories

Resources