I have a windows service called MainService, which is used to monitor SubServices. The SubServices are actually some console applications and started by the MainService via Process.Start() method. Example code:
var subServiceProcess = Process.Start(subService.ServicePath);
The SubServices work perfectly until one of them needs to start another desktop application like the MainService does. Example code:
var desktopApplicationProcess = Process.Start(desktopApplicationPath);
The desktopApplicationProcess is created and we can see it in the taskmanager. However, its GUI doesn't show.
I've tried to run the sub service manually, and then the desktop runs correctly. So, I guess this is caused by that the sub service is started by the MainService.
Can anybody give me some sugguestion?
Thanks a lot~
Have you allowed the Service to interact with the desktop?
Related
Just started implementing a coded ui test automation solution but keep running into an issue when starting the application.
The application seems to start just fine but no matter what I always get an exception stating:
Microsoft.VisualStudio.TestTools.UITest.Extension.FailedToLaunchApplicationException: "The application cannot be started. This could be due to one of the following reasons:
1) Another instance of the application is already running and only one instance can be running at a time.
2) The application started another process and has now stopped. You may need to launch the process directly.
3) You do not have sufficient privileges for this application."
The application is a little strange as it currently is setup to run off of a setup.exe so the user always has the latest version.
Am I missing something in my code (sample below)? Or does the application need to be better set up before I start writing the automation tests. EXE is located in a network location.
ApplicationUnderTest aut = ApplicationUnderTest.Launch(#"\\test.com\\applicationdir\\testenv\\application\\setup.exe");
WpfEdit userName = new WpfEdit(aut);
userName.SearchProperties.Add(WpfEdit.PropertyNames.AutomationId, "PART_UserName");
userName.Text = "TEST";
Currently using a workaround where I start the app via Process and then pass it to the application under test FromProcess(). Seemed to fix the issue.
Probably not the best solution and have to use a Thread.Sleep() but it works for now.
Example:
var process = Process.Start(#"pathToApplication");
Thread.Sleep(2000);
process = Process.GetProcessesByName("process.Name")[0];
ApplicationUnderTest aut = ApplicationUnderTest.FromProcess(process);
I am writing a windows service that occasionaly has to renew IP address of the system and It would call ipconfig /renew to do it.
The code is going to look like this
Process ipconfigProcess = new Process();
ipconfigProcess.StartInfo.FileName = "ipconfig";
ipconfigProcess.StartInfo.Arguments = " /renew";
ipconfigProcess.StartInfo.UseShellExecute = false;
ipconfigProcess.StartInfo.RedirectStandardOutput = true;
ipconfigProcess.Start();
strOutput = compiler.StandardOutput.ReadToEnd();
ipconfigProcess.WaitForExit();
I suppose a windows service is not allowed to show windows/dialogs. So my question is whether renewing ip as above would be a problem in windows service because it may or may not show a console to run ipconfig ?
I think the only issue you're going to face is that of permissions - you should have no problem running a process like this (as long as you don't want to interact with any kind of UI), but your windows service needs to run as an account that will be able to spawn a process and execute ipconfig.
This does not require an instance of cmd.exe. Many command line applications are used in this manner.
A service can use GUI functions and/or create a console. Windows creates a dummy display surface to draw on as necessary. (Obviously, this dummy surface can't interact with the user.)
the following code get the host application ,in this case for CorelDraw application and it run correctly in case of corelDraw in runing and the exe runs by corelDraw:
Corel.Interop.CorelDRAW.Application appDRAW =
new Corel.Interop.CorelDRAW.Application();
app = (Application)this.Host;
but for some complicated reason ,I need to make this code run even without corel is running but I am not going to use the app instance unless the corel is running so any way to get the host application by name or something like that or just to point to the exe of the host application even before it is running
maybe something like
app = (Application) getHostByExe("c:\corelPath\corel.exe");
and advice,
this solved for me
Dim obj As Object
Dim app As c.Application
obj = GetObject("", "CorelDRAW.Application")
app = CType(obj, c.Application)
Can someone tell me what the InteractiveProcessRunner is for? Is it identical to Process.Start?
Here is the class.
And here an example :
InteractiveProcessRunner runner =
new InteractiveProcessRunner(notepad.exe,hSessionToken);
THX
Whit this class you can run a process with the complete environment of the user active: if you call this code from a service, you should find the user mapped resources, the desktop and all the resources that are available when the user is loggen on interactively even if launched from a service ie not logged interactively.
The source code to which your link leads referes to this article: http://asprosys.blogspot.com/2009/03/perils-and-pitfalls-of-launching.html which explains the motivation behind it.
Summary: You can't really use Process.Start() when you want to start a new process as certain user from a windows service. The InteractiveProcessRunner lets you do this (supposedly, never used it so I can't verify it). So it's not the same as Process.Start() - it uses a different Windows API.
I have a project that is deployed to production as a windows service. However for local development purposes it would be useful to run it as a console application. At the moment I have a class Called ReportingHost that provides my core functionality, And a class called ReportingServiceHost that inherits from ServiceBase and allows me to run the application as a service. There is also a program class with a main method that calls ServiceBase.Run on my ReportingServiceHost.
I think I need to write a ReportingConsoleHost class that allows me to run the functionality in a console. Then I need to modify my Main to react to a command line switch and choose one or the other. These are the two bits I am having trouble with.
I have had a look at this and attempted to use that code but my app exits immediately, it doesn't show a console window and it doesn't wait for Enter before closing.
Part of the problem is that I dont have a deep understanding of how these things work. a definitive pattern for splitting my functionality, my two different ways of running that functionality, and a main method that chooses one of these ways based on a command line argument is what I am hoping to achieve.
I suspect your test project was configured as a windows exe, not a console exe. With a windows exe Console.ReadLine will return immediately.
To have a console exe that works both as a service and at the command line, start it as a service project (in Visual Studio) - and add a check on Environment.UserInteractive - i.e.
static void Main() {
if(Environment.UserInteractive) {
// code that starts the listener and waits on ReadLine
} else {
// run the service code that the VS template injected
}
}
You can of course also use a command line switch. I have example on microsoft.public.dotnet.languages.csharp that acts as:
an installer / uninstaller
a service
a console-mode app
depending on the switches
I have done this before by implementing a normal Windows Service (by deriving from ServiceBase), but putting a check in the main method to check for a command line argument.
If the args contain /console, start the console version, otherwise start the service.
Something like this:
internal class MyService : ServiceBase
{
internal static void Main(string[] args)
{
if (args.Length == 0)
{
// run as a service....
ServiceBase[] servicesToRun = new ServiceBase[] {new MyService()};
Run(servicesToRun);
}
else
{
// run as a console application....
}
}
}
My advise? Put all your logic for your service in a separate assembly. (A class library or DLL.) Then create one project as service which references your class library and puts the code to use as services. Create a second console project which also references your class library but which will make it available as a console application.
You would end up with three different projects in your solution but it does allow you to keep things separate. Actually, this would make it possible to extend your service in several other shapes too. You could, for example, create a 4th project as a web service and thus call your service from a web browser on a client system. Because the software logic is separated from the usage logic, you gain lots of control over it.
Be aware that a service will possibly run with more limitations than a console application. In general, services don't have network access by default, don't have a monitor assigned to them to display error messages and in general run with a limited user account or system account. Your service might work as a console yet fail as a service because of this.
There are already two good answers above - but I thought I'd post a link to Brian Noyes' Debuggable Self-Host Windows Service Project blog post - it talks about WCF but should apply to any 'Windows Service'.
The best thing is the sample code - if you can't figure out where the above examples 'fit', grab the complete project and see how it works. Thanks Brian!