Stop C++ Service Application - c++

I created a C++ Service Application and installed the service when I try to stop the service a warning is shown.
The Service contains just one implemented method that is:
void __fastcall TService1::ServiceExecute(TService *Sender)
{
bool a = true;
while(a){
sleep(5);
writeLog("test \n");
}
}
How can I stop the service by brute force, so does not show the warning?

The correct way to stop a service program is to implement a Service Control Handler Function, which can respond to the SERVICE_CONTROL_STOP control code. Usually the handler will set a stop event, which will cause the ServiceMain loop to exit (example here).
If you used a template to generate your service application, you may already have the stub interfaces implemented to do this. If not, you would need to implement them.
Implementing a native Windows Service is not trivial, and cannot be done with just a single executable method. A service application must implement the interfaces used by the Service Control Manager (SCM), such as the Service Entry Point, Service ServiceMain Function, and a Service Control Handler Function. It must also report status and state changes to the SCM. See a complete examples from Microsoft here and here.
MSDN reading reference: Service Programs
If you don't want to implement all of the required SCM interfaces and logic, there are options available from both Microsoft and third parties to run any executable as a service. See Microsoft's srvany.exe method, or Iain Patterson's NSSM for example.

Related

How to complete a service task using camunda rest api

I am using Camunda workflows to automate various processes. I have come across a scenario where the process is not moving from a service task. Usually, we call the task/{taskid}/complete to complete the task, but since the process is stuck on a service task, I am not able to complete that task. Can anybody help me find a way to complete the service task?
You are using a service task. That basically means "a machine should do something". The "normal" implementation is to provide code (a java Delegate or a connector endpoint) that is called by the process engine to execute this task.
The alternativ is to use the "external task" pattern. Think of external tasks as "user tasks for computers". So the process waits, tells subscribed clients that a job is to be done and waits for their completion.
I suppose your process uses the second option? (you can check in the modeler under "Implementation"). So completion can be done through the external task API, see docs.
/external-task/{id}/complete
If it is a connector then you likely will see when checking the log that retries have occurred and that the transaction rolled back. After addressing the underlying issue the service task (email) should be sent without explicitly triggering the service task and the following user task (Approval) should be created.

Calling a service which takes long time to finish from camunda java delegate

I need to implement camunda bpmn where 1 of my task is a java delegate task which calls an api.
now the api what it calls is an async api, because of which the bpmn flow moves to next task after calling the async api but i want is that after calling the api the flow shud stop and then some call back happens through some api to camunda server(hosted as spring boot app).
what would be the best way to achieve the above scenario.
Options for asynchronous communication are
A send task/event follow by receive task/event
https://docs.camunda.org/manual/latest/reference/bpmn20/tasks/send-task/
https://docs.camunda.org/manual/latest/reference/bpmn20/tasks/receive-task/
https://docs.camunda.org/manual/latest/reference/bpmn20/events/message-events/
a service task of implementation type external
https://docs.camunda.org/manual/latest/user-guide/process-engine/external-tasks/
Advanced: Implement asynchronous service invocation using a Signallable Activity Behavior
https://github.com/camunda/camunda-bpm-examples/tree/master/servicetask/service-invocation-asynchronous
From this blog post, whcih provides a detailed explanation:
https://blog.camunda.com/post/2013/11/bpmn-service-synchronous-asynchronous/
You can do this to halt the execution for the specified amount of time.
This will halt the execution for the response

Handling Windows Cryptographic Services (cryptsvc) dependency

I have a Windows service say test which has a dependency on cryptsvc. In some systems (like windows XP), cryptsvc starts later than my service.
One way to handle this is adding cryptsvc as dependent service in my test service.
But this will delay the start of test service as well.
I tried manually starting of cryptsvc using startservice() as part of my service initialization, something like below:
SERVICE_STATUS Status;
Status.dwCurrentState = SERVICE_START_PENDING;
setservicestatus(hTestService, &Status);
ServiceInit();
Status.dwCurrentState = SERVICE_RUNNING;
setservicestatus(hTestService, &Status);
And
ServiceInit()
{
// launch a worker thread that
// calls startservice() to start cryptsvc.
}
But the call to startservice() seems to block for some time and eventually ends with 1056 error (There is already an instance running).
How can I ensure crypt service starts as early as possible, or how can I start crypt service as part of my service initialization. Note that I don't want to strictly ensure that crypt service comes up before my service gets up, but crypt service should be up as soon as possible.

A new Thread should be created on ServiceMain?

The MSDN says that:
"The ServiceMain function should create a global event, call the RegisterWaitForSingleObject function on this event, and exit. This will terminate the thread that is running the ServiceMain function, but will not terminate the service..."
So the question is: A new Thread should be created inside the ServiceMain function to execute the service code, or I can simple set the service to RUNNING state and uses the ServiceMain thread to run the service code? If the ServiceMain thread is used to run the service code the SCM will remain locked, even if the service state is set to RUNNING?
I do not think the way of implementing services described by that statement from MSDN is the only possible way. That would contradict MSDN service example at http://msdn.microsoft.com/en-us/library/windows/desktop/bb540476(v=vs.85).aspx . In the example the service waits for events in the same thread that called ServiceMain. This way is probably better for simple services that work just fine with a single thread.
If you choose to use RegisterWaitForSingleObject way you do not have to create threads explicitly. MSDN page for RegisterWaitForSingleObject says: "New wait threads are created automatically when required." You do have to open I/O channels you service is going to monitor and bind their handles to thread pool before exiting ServiceMain.
MSDN says: "The Service Control Manager (SCM) waits until the service reports a status of SERVICE_RUNNING. It is recommended that the service reports this status as quickly as possible, as other components in the system that require interaction with SCM will be blocked during this time."
The control dispatcher creates a new thread to execute the ServiceMain function for the service. The ServiceMain function should perform the following tasks.
5.. Perform the service tasks, or, if there are no pending tasks, return control to the caller. Any change in the service state warrants
a call to SetServiceStatus to report new status information.
From this example follow that you can perform more complex initialization tasks inside the ServiceMain function such as creating additional threads.
Guidance for creating Multithreaded Services.

Correct way to register for pre-shutdown notification from C++

I write a local service application using C++ and I can't find the correct way of registering for a pre-shut-down notification (for OS later than Windows XP). I believe that SERVICE_CONTROL_PRESHUTDOWN notification has been added since Vista, but when you call SetServiceStatus do we need to specify:
dwServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_PRESHUTDOWN;
or
dwServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PRESHUTDOWN;
You cannot accept both a shutdown and a preshutdown if your service is correctly coded. The documentation explicitly states this.
From http://msdn.microsoft.com/en-us/library/windows/desktop/ms683241(v=vs.85).aspx:
Referring to SERVICE_CONTROL_PRESHUTDOWN:
A service that handles this notification blocks system shutdown until the service stops or the preshutdown time-out interval specified through SERVICE_PRESHUTDOWN_INFO expires.
In the same page, the section about SERVICE_CONTROL_SHUTDOWN adds:
Note that services that register for SERVICE_CONTROL_PRESHUTDOWN notifications cannot receive this notification because they have already stopped.
So, the correct way is to set the dwControlsAccepted to include either SERVICE_ACCEPT_SHUTDOWN or SERVICE_ACCEPT_PRESHUTDOWN, depending on your needs, but not to both at the same time.
But do note that you probably want to accept more controls. You should always allow at least SERVICE_CONTROL_INTERROGATE, and almost certainly allow SERVICE_CONTROL_STOP, since without the latter the service cannot be stopped (e.g. in order to uninstall the software) and the process will have to be forcibly terminated (i.e. killed).
As noted by the commenters above, you will need to choose from either SERVICE_ACCEPT_SHUTDOWN or SERVICE_ACCEPT_PRESHUTDOWN (Vista or later). If you are using SERVICE_ACCEPT_PRESHUTDOWN, you will need to register your service with the SCM using RegisterServiceCtrlHandlerEx instead of RegisterServiceCtrlHandler else you will not be receiving the pre-shutdown notifications. The handler prototype also changes from Handler to HandlerEx.
Another point to note is that handling pure shutdown events is limited to 5 seconds in Windows Server 2012 (and presumably Windows 8), 12 seconds in Windows 7 and Windows Server 2008, 20 seconds in Windows XP before your service is killed while stopping. This is the reason why you may need the pre-shutdown notification. You may want to change this at \\HKLM\SYSTEM\CurrentControlSet\Control\WaitToKillServiceTimeout.
In the comment from alexpi there is a key piece of information. I found that the service handling PRESHUTDOWN needs to update the service status with a new checkpoint number (repeatedly) before WaitToKillServiceTimeout has elapsed. My server was configured to 5000 ms and my service only updated every 12000 ms, and the server went into the SHUTDOWN phase, which caused my attempt to stop another service to return the error that the shutdown was in progress.
These two notifications seem to be different as I get it from the documentation. If what you need is really to enable your service to recieve preshutdown notification, you should go with: dwServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_PRESHUTDOWN; But if you also want to enable your service to receive shutdown notifications, you should go with your second option.