I would like to automate a windows app that comes only with as a GUI app (no support for command-line). The automation itself is relatively straightforward with AutoIt.
Yet, I am wondering, is-it possible to launch the Windows App from with a windows service (that would simply call the AutoIt script)?
Even if Auto-it can work with UAC, you will most likely run into Session Isolation troubles - i.e services and desktop don't mix and send messages to each other, unless explicitely coded to pass through it.
So it's possible, but it's not a piece of cake either.
You probably want to look at : Launching a .Net winforms application interactively from a service
While not at all advised because of complications associated with Session 0 isolation in the latest versions of Windows, AutoIt scripts can certainly be invoked from a Windows Service. Please see this page for a few sample scripts that work as expected when called from a Windows Service.
Unfortunately though, not all of the AutoIt functions seem to work in Session 0. We ran into trouble with the "Win*" routines (WinActivate, WinExists) so you should probably avoid those if you can. And since the documentation does not highlight the problematic functions be sure test thoroughly!
Related
A project I'm writing at the moment requires a Windows Service to be written as it needs to run unattended. One requirement in the specification says that the service should also be able to be run interactively. This is no great problem as I can simply use Reflection to get at the OnStart/OnStop methods and use Console.ReadKey() to pause for keyboard input.
All that's really causing me to pause here is that in order to do this I need to change the output type of the project from Windows Application to Console Application. I'd like someone that has a detailed understanding of the differences between these two choices to explain what the difference is between them and if there are any ramifications for stability in production.
If, while executing in interactive mode, the service is NOT showing Forms, you can change the output type and expect no trouble. If Forms are needed, output type should remain Windows Application. As a general rule, I always start developing service apps as Console apps. It's easy to debug. When it is almost done with testing and debugging, I change to a service app.
I want to know which is the best practice when a piece of software needs to restart, shutdown, logoff or hibernate Windows:
Use ExitWindowsEx API
Use Shutdown command and its parameters
What is the advantages and disadvantages of each approach?
Thanks
I always prefer calling the API (ExitWindowsEx, InitiateSystemShutdown).
Pro API
GetLastError can be used to diagnose errors
You get access to the full API, not just the things exposed by a utility
You don't have to worry about filesystem redirection and whether the tool exists in the home versions of Windows
The documented interface stays the same, command line switches could change or be different in a different language
Pro external tool
Makes some difficult tasks easy to perform (Some things require undocumented API's)
Few bugs, and if there are bugs they are not yours ;)
They are different.
Using API, you can apply more logic in your program, e.g. get the current state, etc.
Using the command, you can just perform the actions.
We are developing C++ apps (lots of MFC) with Visual Studio 2005 on Windows.
From time to time it happens that our nightly builds and/or unit tests hang because some part of some app or helper tool opens a message box in a corner case that is hit by the build.
Since the automated stuff is run (by a Windows Service) without any desktop session attached, obviously no-one can confirm - or even read - the GUI messages.
Is there any way to have Windows prevent apps from opening dialogs? Or maybe a tool that watches a service session that auto-kills any app that opens a dialog box?
I'm thinking that most cases where apps display unexpected popup-messages, it will end up calling one of the MessageBox* functions from user32.dll and it might be just possible to "magically" have these functions fail for a certain login-session? (Just a wild idea.)
Obviously the "right" fix is to have stuff not opening any dialogs, but with 3rd party tools it ain't always possible and with our tools it would be nicer to have a failing unit test that tells me the test "illegally" opened a message box than have a hanging unit test.
(Side notes: We're using Boost.Test for our unit tests and FinalBuilder for our automatic build scripts.)
Note: Removed original tags [continuous-integration build-automation automated-tests] and rephrased question to be more process centric.
You can load a DLL in each of the processes which puts a hook onto MessageBoxA and MessageBoxW. You can either do this manually or via the Detours library. You can then either have it return straight away without calling the real function or you could even implement some form of logging to notify your CI of the error.
We use AutoIt to automatically dismiss dialogs in our commercial run-as-windows-service application. The concept is described and some sample scripts are available here:
http://www.coretechnologies.com/products/AlwaysUp/AutoIt/
Note that some of the AutoIt functions don't work properly in Session 0 (e.g. WinActivate) but you can usually find alternatives. Be sure to test in Session 0!
I have run into a case where a Windows Form application is being run regularly via a scheduled task on a Windows Server 2003 box. The GUI is, obviously, not being used to take in any user input, so it is at best pointless. But is it also dangerous? Could it cause anything to go pop on the box?
It should not really harm.
You may want to create a standard shortcut to the application then in "properties" select the "Run" -> "Minimized" option.
Don't forget to point the task sceduler to execute the new shortcut rather than the direct application.
The GUI is, obviously, not being used
to take in any user input, so it is at
best pointless.
Just because it doesn't take input doesn't mean it does nothing. While the GUI part of it is probably pointless, the application execution itself may not be.
A Windows Form application being run regularly is the same as any other process being run regularly, and it may have been for whatever reason that the developer of the app wanted a GUI to appear while it was doing its thing or may have had plans to allow users to interrupt the running process through the GUI.
The developer may even be using a GUI control for application execution. A "good" example of this would be using a web rendering control for its DOM processing capabilities.
Could it cause anything to go pop on
the box?
If it doesn't correctly dispose of any resources it uses then yes.
I wouldn't imagine GUI apps are any more notorious than console apps for this, but the fact that someone perhaps unnecessarily used a GUI app (maybe they had only been introduced to WinForms projects) is a strong indicator to check the code and make sure all appropriate resources are being disposed of correctly (think 'using' blocks).
We're starting a new custom project right now from a client and one of the requirements is the process cannot be terminated unless the system is shutting down, restarting, or logging-off.
This application monitors the USB interface. We will be using WMI to query the device periodically.
The client want's to run the application on Windows XP Operating System and doesn't like installing .NET. So we targeted Visual Basic 6 as our language.
My main concern is this application cannot be terminated. Our Project Adviser talks about Anti-virus and yes, some of the anti virus cannot be terminated. I was thinking how to do the same in Visual Basic 6. I know there will be API involved on the project but where should I go? so API is ok with me.
I saw some articles that converts the EXE to a SERVICE, create Windows Service in Visual Basic 6, etc.
So please .. share your thoughts.
If you want to be evil, you can call the (officially) undocumented RtlSetProcessIsCritical NTDLL function. This will immediately BSOD the machine if your process is terminated.
You cannot create a process that cannot be terminated without some sort of kernel-mode hooking, which involves writing a driver. You might want to look into Rootkits: subverting the Windows kernel if you're interested in that. However, even with kernel-mode hooking there are still numerous ways to terminate processes. The alternative is to use user-mode hooking, easily bypassed but enough for very simple projects.
The solution you want to use will depend on how far you want to go with the termination protection. And even if you do succeed in preventing process termination, there may be ways of preventing your application from working properly - e.g. killing the WMI service.
I think you want to look at writing an NT Service.
More info here: http://www.montgomerysoftware.com/CreatinganNTServiceinVisualBasic6/tabid/161/language/en-US/Default.aspxlink text
It's really frustrating coding in VB6 right now specially I dumped my head in C# for 2 years though I coded in VB6 for 5 years..
Moving back is a pain as if I am starting a new programming language.
To be honest, you are trying to do something in VB6 that it really isn't that great at.
When you say 'cannot be terminated' - what do you mean by that? There are several levels there:
a) App shows a window but the user cannot close it with the X button, or it does not show one
b) App shows no windows or maybe sits in task tray
c) App shows no windows and cannot be shut down from the Applications tab of task manager
d) App cannot be shut down from the process list of task manager
(a) and (b) are probably easiest to do in straight VB. (c) is still possible, but getting uglier. (d) gets you into hack territory and would almost certainly be frownd upon if you did manage it.
If you really need to stop users closing then you can probably hack it to a greater or lesser degree, but the real answer is as the others have said - a system service (this is exactly the srt of thing they were intended for). However that is one thing that VB6 isn't good at so the best solution to your problem is c#.