I'm trying to run external Application from service,
I've tried different solutions but nothing works so far.
ShellExecute I found out it cannot be used from a service
and WinExec
You can run applications from a service, but since Vista you won't see them at the users dektop.
Running the taskmanager will show that applications are started nevertheless.
MSDN Interactive Services
There are existing mechanisms to interact with the desktop yet, but that would be beyond the frame.
Launching an interactive process from Windows Service in Windows Vista and later
Services run in session 0, but that's a non-interactive session. So if the other process is interactive you need to make sure that it runs in an interactive session. That's quite trick to arrange, but not impossible. Details can be found here: http://blogs.msdn.com/b/winsdk/archive/2009/07/14/launching-an-interactive-process-from-windows-service-in-windows-vista-and-later.aspx
Related
I'm attempting to use psexec to spawn a process on a remote machine (for automated testing purposes) and noticed that the spawned process wasn't correctly responding to a message (WM_GETOBJECT, but that's another question entirely). I opened spy++ in an attempt to see why, but I couldn't log any messages going to my process' window. The window properties also indicated that the "Windows Proc" for the window was "Unavailable":
.
I think this is a behavior of Windows services since psexec uses an embedded service on the remote machine to launch the requested application. I was logged onto both machines with the same credentials so I don't believe it is a user security issue but rather a service-related behavior.
As a sanity check I wrote a quick standalone server and client to execute a program remotely and everything worked as expected: the Window Proc was no longer "unavailable" and I could spy on messages.
I used the normal Windows Calculator (calc) for all my tests, i.e.:
psexec.exe -i \\other-machine calc
My question: Can someone confirm, explain, and/or cite why I can't see message queues of processes spawned off services? Also is there a workaround to this? I'd rather use psexec than my custom solution. Bonus if you can also explain why WM_GETOBJECT doesn't return my custom UI Automation provider in this situation as well, as that's my original problem.
I have a delphi app that logs data from various places and writes the data to a file. The app has quite an extensive GUI to allow display of the data, configuration of the options, etc.
One user has requested that the app be changed to that it can be run as a service. His reasoning is that the app could then be started at boot time and run without any user being logged in and would be available regardless of who was logged in.
My question is this: Is there any other solution that would enable me to install the app as it now exists so that it would still run with no user logged in and still be available to all users?
My gut feeling is that converting the app to run as a service is not trivial. I assume you would need 2 apps - the "headless" service application, and a GUI that was run by users on demand that could interact with the service (comments welcome here also).
I usually create my application in such a way that it can be started as a service or as a GUI, via a commandline switch /GUI.
When the application runs with a GUI, I instantiate and start the service class "manually".
Advantages:
It'll run the same code, making it very easy to debug the service. You can just put breakpoints and step through your code without having to "attach" to a running application.
Because of the GUI, you can see what your service would be doing, and interact with it, via listviews and buttons, even on remote servers where you don't have a debugger. Having to interact with your service via logs and configurations is crappy and slow.
Example dpr, from a project that works like this:
program xxxx;
uses
SysUtils,
SvcMgr,
.......;
{$R *.res}
begin
GlobalAppId := 1;
MapMatcherController := TMapMatcherController.Create(nil);
try
if FindCmdLineSwitch('GUI',['/','-'],True) then
begin
Forms.Application.Initialize;
Forms.Application.MainFormOnTaskbar := True;
Forms.Application.CreateForm(TfrmMain, frmMain);
Forms.Application.Run;
end
else
begin
SvcMgr.Application.Initialize;
SvcMgr.Application.CreateForm(TsrvMapMatcher2, srvMapMatcher2);
SvcMgr.Application.Run;
end;
finally
MapMatcherController.Free;
end;
end.
Oh, another thing to keep in mind is that services usually run as a "system" user, which means you'll have different privileges and settings (for example drive letter mappings).
There are commercial (and free) solutions like Firedaemon, which will run (almost) any application as a service.
On a sidenote, it shouldn't really be hard to separate logic and user interface - you should've done that already when you developed the application. Just because Delphi makes it easy to write business logic in the code behind associated with the user interface, that doesn't mean you should really do it. Have a look at the presentation pattern's at Martin Fowler's site.
In general is possible to have a mixed single exe which in turn runs as a service or runs as a full GUI standard application.
How much effort your application needs to fit this category is matter of how is it designed, specially in the kind of coupling it have between business logic and user interface logic.
One great example of this kind of application comes with Delphi itself: scktsrvr.exe in your $DELPHI\bin directory runs as a GUI application or as a service (run scktsrvr.exe /install to auto-register the service and use management console to start/stop it.
in folder $DELPHI\source\db you will find the project files (scktsrvr.dpr/res, ScktCnst.pas, ScktMain.pas/dfm). Take your time to inspect how is it done and, who knows... maybe this is what you're looking for your application.
Take in account since Windows Vista interactive services are not allowed to interact with the user at his/her desktop. An administrator have to enable the interactive services detection and the user have to change to session 0 desktop in order to interact with your service (by interact it means to see and interact with your service forms)
You can try to use svrany, a tools to run an application as service.
It's parts of Server Resource Kit Tools.
try this link for 2003 server resource kit download.
It depends a little on your application, but generally it is achievable. Try this: http://iain.cx/src/nssm. Don't forget to start all services that you application depends on BEFORE you start your application as a service. Google around for info on how to do that.
You could write a simple service that starts your application. But if you care about your app future, I would go the service way. Yes, you would have to split the application in two pieces, the client/GUI part and the service itself, especially since Vista and 7 made much more difficult for a service to display a user interface for security reasons.
Services have several advantages, they run in their separate session, they can be set to run with a given user that could be different from the logged-on one, only user with proper privileges can control them, Windows can automatically restart them (or perfom other actions) when they fail.
I built an application that is running as a windows service and is installed through my code.
All is fine except at logon.
When at the first windows xp/2003 server logon screen, I am not sure if the service is running at all. If it is, then it does work as it's not functional (the service IS USING WINPCAP so that could be an issue).
The service settings are set to "interact with desktop" and run as SYSTEM.
How can I ensure the service will start before windows logon? Also how can I make sure it is running even after I log off?
There are a couple of issues to consider.
First, you can check if your service really is running before login and after logout by logging events to the Windows Event Log. Pretty much all services do this whenever they start and stop and yours should do the same.
It may be that WinPcap is part of the problem. There are a couple of golden rules for using WinPcap in a service.
1a) Your service must not do anything that might cause the WinPcap service to try to start up while your own service is starting up because this will cause a deadlock in the Windows Service Control Manager. That means that if the WinPcap service is not already SERVICE_RUNNING when your service begins startup, you must not do anything that might cause it to start until after your service is SERVICE_RUNNING.
There are two ways to ensure this. Either make your service dependent on npf, the Network Packet Filter service. Or do not call any WinPcap function until after your service is SERVICE_RUNNING. I've not tried this latter method. I presume then the WinPcap function will block until npf is SERVICE_RUNNING.
1b) If you make your service dependent on npf, you will also have to make it dependent on nm (Network Monitor Driver) - if and only if nm is installed on the system. nm provides WinPcap with PPP/VPN support, and WinPcap always tries to use it if installed. Obviously, if you make nm a dependency of your service and nm isn't installed then your service will fail to start.
I don't think there is a guaranteed way to ensure that your service starts up before the desktop appears. But you might be able to help things along by creating a Service Control Group, adding it to the end of the existing list of Service Control Groups, and putting your service into this group. I'm not entirely convinced that this is an 'approved' way to get your service to start sooner, because if there was an approved way then everyone would do it and it wouldn't work any more. But there is a suggestion that services in a group are started before services not in a group.
Look at HKEY_LOCAL_MACHINE, "SYSTEM\CurrentControlSet\Control\GroupOrderList" and HKEY_LOCAL_MACHINE, "SYSTEM\CurrentControlSet\Control\ServiceGroupOrder" and do a bit of Googling.
I have created a Datasnap service, using Bob Swart's white paper as a guide. I have been debugging and deployed succesfully using the VCL Forms application as a server. But when I try to deploy the service version, it installs ok, I then try to start the service and it immediately stops. The error in the event log would suggest that the port set is already in use, I have tried different port numbers for both the TCPServerTransport and the HTTPService without any joy. The DSServer is not set to Autostart as I want to set the Port number from a configuration file. The error message displayed in the event log is:
Service failed on start: Could not bind socket. Address and port are already in use..
I have also tried writing to a log file on start up and execute but it looks as if it is not getting this far.
Solution needed asap, before I have to revert back to a thick client which I do not really want to do.
Thanks
Firstly get a copy of TCPView from the Sysinternals suite (now run by Microsoft) and use it to monitor which app is using the port you want to use.
I would hazard a guess that if the app works fine as a stand alone (as you say it does) and you are trying to use the same port in the service then perhaps the service app is opening up the port at startup without you realizing it and then when you try to open the port manually the app finds it already in use. Or somehow the app is trying to open the port twice. The first time is successful but, maybe due to an event or an unexpected code path, the app tries to open it a second time and fails. TCPView will help spot this.
If you are sure that the port you have configured is actually free and not in use by any other software on the machine, then there might be some anti-virus / security software running that is blocking all software from listening on either specific ports or on any port except a few configured ones. The message you are getting could be one of the symptoms of how the anti-virus / security software handles attempts by apps to start listening on a port.
I am a seasoned Delphi developer and would like to create something like seamless terminal services where an application is executed on a server but appears on the the desktop of the client.
To someone working on the server I don't want them to see the remote application running (except if they looked in at the list of running processes).
I'm lost as to how to go about this, where to start, how to get an application to render to a surface other than the servers desktop.
Starting from 2008 Terminal Services (which has been rebranded to Remote Desktop Services) offers RemoteApps which do exactly what you describe. Citrix (XenApp) can do this on all windows (server) versions. So you might want to look at those products before deciding to recreate them yourself.
If you do decide to go on, this link might be interesting, it's a sample project called "Extending Microsoft's Terminal Services Client To Provide Seamless Windows"
From what you are describing, I'd say you should be looking at writing a windows service (not terminal services) and using a inter-process-communications (IPC) system to get status information to a "client" application that can be run by the appropriate user, either on the same machine or another over the network.
Myself, I do exactly this using the RemObjects SDK which makes my client application look like it is just making function calls, but actually they go to the server which implements them. The server can then get on with its job in one (or more) thread, and all the user interface is done in the client which finds out what to display using the IPC channel.