Running a GHC created windows executable as a service - windows

I have compiled a program on Windows Server 2008 using GHC 7.6.3 32-bit. I'm attempting to run it via a service within windows on boot-up (and ideally keep it up). To do so I have created a service with the following command successfully
sc create stworker binPath= "C:\Users\vagrant\Desktop\worker.exe"
The problem I'm having is that when I attempt to start the service I receive the following error (see image below).
The executable runs fine when I double click it. So not sure why Windows wouldn't allow the service to be run.
I don't think this is an issue w/ GHC. I'm under the assumption that GHC compiles to native code and not MSIL.
So any ideas why I can't run my executable as a service?

As mentioned in the comments, you need to actually implement the Win32 service API for your program to behave as a Windows service, and you can do this using the Win32-services package.
There's also a wrapper package Win32-services-wrapper that I wrote that aims to provide some of the boilerplate and handle logging, so that defining a service looks like this:
main =
defineService $
Service {
serviceName = "Service",
-- Start the service given a debug handle to write to.
-- Make sure not to use stdout or stderr as they don't exist.
-- Any state needed by serviceStop can be returned here -
-- the Service type takes the type of the state as a type parameter
serviceStart = \debugHandle -> ...,
-- Stop the service given the service state returned by serviceStart
serviceStop = \serviceState -> ...
}
There's a real example of using it in darcsden.

Related

In Windows, how can I check the executable run by a Service?

The "Services" window enumerates all of the system services, but inspecting the properties of a given service doesn't show what is actually running behind the scenes.
Take, for example, the Apache2.4 service (shown in the image below), how can I see what executable is being run by this service and with what arguments?
Example from "Services" window
In the Command Prompt you can use the sc program with the qc command (query configuration) to get this information for any service.
For the example given,
> sc qc Apache2.4
will give you information about the service, one section of which is the BINARY_PATH_NAME which will detail the exact command (with arguments) run by the service.

Creating service-based COM instance from CLSID

Windows Subsystem For Linux (new techonology in Win10) uses LxssUserSession service. This service is undocumented, but it is used as API for WSL (bash.exe uses this service to run ELFs). As i can see, it is part of COM: There is CLSID record in registry that has AppID. And AppID has LocalService record: LxssUserSession.
I am not familiar with COM, but if I understand it correctly, there should be COM component backed by this service. I am not able to create instance of this COM from script since there is no ProgID, but I tried to instantiate it using OleView. How ever, it reports that CoCreateInstance returned error. How to debug this error? Could it be that COM component can't be created and used for something different (i.e. there is some other interface). Is it generally possible to work with undocumented COM component? Can I trace bash.exe calls to this service (something like logger.exe or ltrace but for COM?)
Some background:
Here is error I am getting: http://s32.postimg.org/wpthro5kl/error.png
bash.exe != /bin/bash. bash.exe is PE (Win64 bin app) that connects to LxssUserSession and asks it to run /bin/bash (which is ELF (linux app!). bash.exe is better be called "WLS.exe", but for some reason they called it bash.exe.
Please see here: https://msdnshared.blob.core.windows.net/media/2016/04/LXSS-diagram-1024x472.jpg and here is its headers http://s32.postimg.org/khjjf81th/bash.png .
So, I am sure bash.exe uses COM to connect to LxssUserSession and LxssUserSession uses Pico (Psp..) functions to launch ELF as "pico process" (See here https://blogs.msdn.microsoft.com/wsl/2016/04/22/windows-subsystem-for-linux-overview/).
Both are undocumented, but I believe I can use COM some how, but I am getting error which I provided as first link:(
I was able to instantiate object using OleView by setting default impersonation level to "Impersonate" in component services config (you may need to reboot). I can see ILxssSession interface now. But since there is not IDispatch and no TLB, there is nothing I can do: methods are unknown to me(
I just doing the same kind of project. What I do is reverse engineering "bash.exe" to see how it work. Currently, I can create an insurance of LxssUserSession and call some method in it. But it still not complete. You can find it source here.

Timeout when trying to access QtDBus Objects that where created in a Windows system service

I want to create a Windows system service using QT/MinGW which communicates with other applications over DBUS (from freedesktop.org). For the moment DBUS is running as a "service" by meaning of it was installed as service using the instsrv/srvany tools (however, the DBUS will get it's bus-service-win later). Since running as a service, DBUS is running as system bus.
I wrote a simple application to ensure that DBUS is working (creates on simple object with 1 method and exectued it with QDBusViewer). Well, that worked.
Next I tried to use the same DBUS stuff in the ServiceMain from my service, where ServiceMain is a member of a class created by our own). I can see the object in QDBusViewer, but as soon as I select it, QDBusViewer reported a timeout (no reply) after it stucked for a while.
I have seen this behavior in my test application, and could fix it by creating a QCoreApplication "app" and "block" on app.exec() after the DBus object have been created. I tried the same in the service, but got a warning that QCoreApplication was not created in the main thread, and the problem still persists.
I tried to create "app" in the function that calls StartServiceControlDispatcher() and run app.exec in the ServiceMain, but app.exec() quits immediately with a the error "must be called from the main thread".
How can I get over this? Have much thanks in before.
Comparing my own service class against the QtService class from "QT Solution" fixed my problem.
All after all I needed to put the StartServiceControlDispatcher() function into a QThread and change the method of my service class in a way that exec() is only executed when definitely running in the context of the SCM.

Can a Windows service install another Windows service?

I am having trouble when I have one Windows service try to install another Windows service.
Specifically, I have a TeamCity agent running tests for me on a Windows 2008 AWS instance. The tests are written in Java, which shell out to a .bat script to install a service (let's call it Service A), giving it a unique name each time.
The offending line is in the .bat script: sc create "%serviceName%" binPath= %binPath% DisplayName= "%serviceDisplayName:"=%" start= %serviceStartType%. I believe as long as the service name is unique that should work.
And indeed it does work if I run the tests manually on the command line, using an administrator account. Service A is installed, the test completes and Service A is uninstalled at the end.
I have tried running the TeamCity agent as LocalSystem, as Administrator, and as another user that is member of the administrators group. I have also tried disabling UAC completely.
Presumably the problem is access denied type errors, although that is not clear at this point. There are a few avenues to explore still, but it is a simple question really: are processes running as services forbidden from installing other services? Are there special things I have to do to configure the machine/ account to allow it to do this?
The point of the test it to install and use Service A, so workarounds are not relevant - Service A must be operated as a black box.
Thanks!
There are no restrictions on creating services with regards to how the creating process can execute, as long as the process has the appropriate permissions. That is to say, a process could be running as a service and create another service -- the only consideration here is the appropriate permission level.
The problem that often occurs with running batch scripts from within processes (as opposed to directly through user input on the command line) is that the environment expected isn't always the environment that is loaded. In this case, it appears that the env variables referred to in the batch script weren't properly set when running as a service, which of course then caused the service install failure. Correcting the environment loaded when the batch script is shelled out is the correct solution here.

Creating a service in windows

I want to create a windows service to run an exe on start up.
Actually i am using mongodb.
Every time i need to start the mongod.exe at first to perform all operations.
Please give some suggestions to create a service to start this exe on start up.
A Windows service needs to communicate with Windows' service control manager.
I guess that mongodb does not support this out of the box.
So you either need to create a small service framework that starts mongodb or you can use something like srvany.exe (http://support.microsoft.com/kb/137890/en-us/).
Service Installation can be done with SC.EXE
MongoDB already runs as a service. Why aren't you installing it the usual way?
I got answer from this link.
Its working fine.
http://docs.mongodb.org/manual/tutorial/install-mongodb-on-windows/#mongodb-as-a-windows-service

Resources