Successfully close dialog in another process - c#

I have a question. The problem is that I have another process which invoked ShowDialog() method, I need to close this dialog from another process but I need to close it with returning DialogResult.OK.
So from my .net program(another process) I want to close it successfully. I tried to use winapi to solve this problem, tried EndDialog function, but it returns error that ACCESS_DENIED. Tried to use hooks but those return error_no_token.
I need this to start msi installer silently. I start it with /qn switch, but this damn installer has embedded action that shows dialog in any case. I tried to close this window with sendmessage function, but in this case installer says that it is error, and rolls back the install process. I can fill all the values programmatically and click OK button on the dialog, but it requires to fill ALL THE VALUES, and there are lots of them, so it is time consuming. The purpose of this dialog is to create config file, which I can create manually later, after installation.
Is there any way to accomplish this task?

It sounds like the main issue you are having is doing a end-run around the validation for the text fields. As you said you would be editing the configuration files later just put some dummy values in each box and click the OK the way that causes the validation to happen.

Sometimes you need to change a bad design to remove the need to do a hard task, rather then keep fighting the system.
A UI is owned by one process, and apart from automating tests, should only be changed by that process or the user.

There used to be installer toolkits aims at system admins, that would watch the registry and file system while running a installer and then create a custom MSI file to automate the process. This may be another way for you to go.

Related

Is it possible to autoupdate app without closing it?

I have a Win UI 3 app that checks it here is a new update available, it dowloads the installer, but is it possible to execute such installer without closing the app?
How execute the installer from the code?
How to handle tha installation from within the app without closing?
Is it to complex? or should I just have the user do it manually?
NO. The executable is in memory (and may have locked files or resources). In order to get an update it will have to be relaunched. If your code is modular, think plugins, these could be updated in place.
Most applications launch a helper app then close themselves, because Windows usually blocks changes to executable files that are in use.
The app might pass its own process ID to the helper app so that it can wait for the process ID to disappear before attempting to update the file.
If not, the helper app might scan the process list for the EXE name, and pop up a message asking you to close the main app. It repeats this until there are no instances of the EXE in the process list.

How can I force another program to not show any dialog when I run it with Process.Start()

I'm not sure if it's possible anyway. But my question is, can I force a program to not show any dialogs when I run it with process.Start()?
I have a program where I call another program in a foreach loop. It is a fileconverter. Unfortunately some files don't exist any more or the user gives the wrong filepath. If that happens, the converter shows an error with a messagebox. But i don't want to see that box, because if the user wants to convert 10000 files, but has the wrong path in settings, 10000 messagboxes appear and force the system to crash.
I have tried to kill these processes but they have the same name in the processes as the converter itself. I can handle it with a Thread.Sleep but then my mouse is flickering all the time while my thread is running. This is just a little bit better than the messageboxes.
If there is a way, I would be very thankful if you could tell me :)
Regards Schlinger
Most probably it's not possible. There is no built-in way to prevent any executable to show any dialog box.
Depending on the executable you're running, with some luck it might expose a command line version that accepts some quiet or noui parameter, but it's unlikely.
Or you could try programmatically closing those dialog boxes, as suggested.

Directions and Opinions on Creating Update System for the Application

I just try to figure out a good solution on designing the update process for a windows form application i created. I think of a button inside the app for manual checking of an update and checking when starting the app. Only I'm not familiar with technics. I though to have the update setup file in a FTP Server and checking the server for an update with a txt file in there with filename and version info. When app is finished downloading the update, closing and starting the update setup file.
Any suggestions, opinions on the subject?
Application updates these days are one of those necessary evils. Thinking of applications that update automatically, I tend to group them into two categories:
Clean updating, once a month or less often, a speedy update without a lot of nagging or clicking. And definitely no sneaky software included like toolbars and desktop search programs... Firefox tends to be "nice" about updates, though its addons can be naggy.
The other group nags constantly, requires a lot of button clicks or that you reboot, takes a long time to 'unpack' (Adobe Acrobat, looking at you), changes settings against your wishes (Java), or is just generally unpleasant.
With those points in mind, design your automatic update to be as user-friendly as possible, and plan on your users sometimes wanting to skip the update (unless it is critical to operation).
At my company we have a small application that requires updates, but also must function in a very time-sensitive environment. To facilitate updates, we have it do the following:
At startup, a text file is checked on an internal URL (this could be an HTTP or FTP call). The version number is compared to the contents of the file.
If the software is up to date, nothing more is done. If not, a dialog is presented informing the user that the application must perform an update. (In our case there is no option to cancel or wait, but I highly recommend it if you can.)
A setup file is downloaded from the same site, and launched via Process.Start command, with some switches to perform an unattended install/update.
The application is launched after installation and the interruption to user is minimal.
Some things you may want to do differently:
If not checking for updates at startup, provide an option to schedule update checking or manually perform an update check from (for example) a Help menu.
If possible allow the user to cancel or delay an update; there's nothing more frustrating than trying to get work done with a popup dialog asking you to perform an update every few minutes.
Make sure you test your install packages or patches before deployment! (Voice of experience!)
Use ClickOnce http://msdn.microsoft.com/en-us/library/t71a733d%28VS.80%29.aspx
http://www.15seconds.com/issue/041229.htm
Kind regards.

How to monitor Windows Dialog?

I am looking for a way to monitor Windows dialog during a MSI deployment. Here is my situation: we have machines deploying daily MSIs and once in a while, one of them fail and shows a Windows dialog with an error message.
I am trying to find a way to write a script (maybe in Powershell) which will run every minutes and look for a Windows dialog with an OK button. Is there a simple way to do that?
Thanks!
You can depoly a MSI with options to not display a GUI at all.
Using MSIEXEC with the /quiet option.
Deploy via active directory to machines should not have this problem so I'd be interested in how you are deploying the MSI.
Rather than try to click the dialog, is there a way that you can determine the condition that will cause the error, and handle it?
Although you will find some methods for enumerating windows and posting click messages to them, there are some other things that you migth want to consider:
What if an unrelated dialog box appears that has an Ok button? It could cause problems for your users if an "Are you sure you want to delete the contents of c:\" gets auto-ok'ed.
Also, if your setup is running on Vista/Windows7/server2008 with UAC turned on, then your script will have to run with admin privileges, or any click messages will be rejected.
Can I assume that you are deploying updates to multiples machines (and effectively you wish to know if an update was successful?)
If that is the case, would it not be possible to code such that when the deployed software executes, it reports (via email?) the PC name and the Software Version Number?
You could then simply right a script to start the application periodically and then close it as well.
Darknight

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