How do you run a DART application as a windows service? - windows-services

I've been researching the possibility of using the DART language for my next project. The only thing really holding me back at this point is that I'm unable to find a way to run a DART application as a windows service. I have run searches on Google and read through much of the documentation on the DART website. Most of the information I found was related to creating a server in DART but nothing regarding windows services.
Can someone either point me at directions or detail the steps necessary to do so?
Thanks,
Jon

=== Latest Update ===
My original answer consisted of using C and Dart FFI to boostrap the Windows Service. However, none of this is really needed as a much, much, simpler solution can be had by using Docker with Windows Containers.
Instead of actually running the application as a Windows Service, the alternative is to compile it to an executable Windows console application, create a Docker file and a Windows Docker image that will include that application. On the server you will need docker and you can simply run the image with a --restart option. To test this out, Windows 10 supports Docker with Windows containers.
So, the simple solution is, we don't really need to run Dart code as a Windows Service, because we can run it as a docker container on the server.
=== Original Answer ===
I am arriving really late to the game, but I figured a way around this problem without having to use 3rd party applications.
My solution is kind of an hack, but hey, it works. I am compiling the dart application as an executable and then registering it as a Windows Service, using sc.exe create. The issue with sc.exe create is that the main function of the application needs to perform some extra steps to inform Windows that it is running. If this isn't done, Windows service gets stuck in a "Starting state".
I don't think there is a pub package available to perform this duty. However, there are 2 things we can use: Dart:FFI, and the following article from Mohit Arora that explains how to create a Windows Service in C++. https://www.codeproject.com/Articles/499465/Simple-Windows-Service-in-Cplusplus
I grabbed Mohit's code and made a ton of changes (including backporting it to C, because... C++)
C
Here's the full code of the Service.c file:
// Provides an API for Dart console applications to
// integrate themselves as Windows Services
// The entry point to this API is the Init(...)
// function at the bottom of this file.
// The Init(...) function registers the ServiceMain(...)
// function as the actual windows service function.
// the ServiceMain function does the following:
//
// 1. Registers the ServiceCtrlHandler(...) function
// as the service control handler, which is essentially
// tasked to handle control requests (in this case we
// are only handling the request to stop the service).
//
// 2. Creates an event object that and then waits indefinitely
// for the event to be set.
//
// The ServiceCtrlHandler(...) function responds to a
// close request by setting the event created by the
// ServiceMain(...) function, essentially freeing
// the latter from the indefinite wait and terminating
// it.
// The functions in this file don't actually
// do any work, but keep the Windows Service
// alive. The work be initiated by the calling
// application either before or after the call to Init(...).
// Because this was developed for the purpose
// of enabling Dart applications to run as
// Windows Services, it it the Dart Application
// that needs to call Init(...) using Dart FFI.
// It must also be the Dart Application to
// spawn an isolate that does the actual work
// before the call to Init(...)
#include <Windows.h>
#include <tchar.h>
#include "service.h"
SERVICE_STATUS g_ServiceStatus = { 0 };
SERVICE_STATUS_HANDLE g_StatusHandle = NULL;
HANDLE g_ServiceStopEvent = INVALID_HANDLE_VALUE;
LPWSTR w_service_name;
void UpdateStatus(
DWORD newState,
DWORD checkPoint,
DWORD exitCode,
DWORD controlsAccepted)
{
g_ServiceStatus.dwControlsAccepted = controlsAccepted;
g_ServiceStatus.dwCurrentState = newState;
g_ServiceStatus.dwWin32ExitCode = exitCode;
g_ServiceStatus.dwCheckPoint = checkPoint;
SetServiceStatus(g_StatusHandle, &g_ServiceStatus);
}
// Responds to control events. This implementation is
// only responding to the SERVICE_CONTROL_STOP event
// This method signals the ServiceMain function
// that it can stop waiting before terminating.
void WINAPI ServiceCtrlHandler(DWORD CtrlCode)
{
if (CtrlCode != SERVICE_CONTROL_STOP || g_ServiceStatus.dwCurrentState != SERVICE_RUNNING)
return;
UpdateStatus(SERVICE_STOP_PENDING, 4, 0, 0);
SetEvent(g_ServiceStopEvent);
}
void InitServiceStatus()
{
ZeroMemory(&g_ServiceStatus, sizeof(g_ServiceStatus));
g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
g_ServiceStatus.dwServiceSpecificExitCode = 0;
UpdateStatus(SERVICE_START_PENDING, 0, 0, 0);
}
// This function essentially creates an event object
// and enters a holding pattern until that event object
// is set by the ServiceCtrlHandler(...) in response
// to a close request.
// The function doesn't actually do any work,
// except to keep the Windows Service alive.
void WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
{
g_StatusHandle = RegisterServiceCtrlHandler(w_service_name, ServiceCtrlHandler);
if (g_StatusHandle == NULL)
return;
InitServiceStatus();
g_ServiceStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (g_ServiceStopEvent == NULL)
{
UpdateStatus(SERVICE_STOPPED, 1, GetLastError(), 0);
return;
}
UpdateStatus(SERVICE_RUNNING, 0, 0, SERVICE_ACCEPT_STOP);
while (WaitForSingleObject(g_ServiceStopEvent, INFINITE) != WAIT_OBJECT_0)
;
CloseHandle(g_ServiceStopEvent);
UpdateStatus(SERVICE_STOPPED, 3, 0, 0);
}
LPWSTR get_service_name(const char* service_name)
{
int max_count = strlen(service_name);
int size = max_count + 1;
LPWSTR ret = malloc(sizeof(wchar_t) * size);
size_t outSize;
mbstowcs_s(&outSize, ret, size, service_name, max_count);
return ret;
}
/// This is the entry point that should be called
/// by the Dart application (or any application
/// of a similar kind of platform) in order to
/// integrate itself as a Windows Service.
/// It registers the ServiceMain(...) function
/// as the service main function. Please consult
/// the comments at that function to understand
/// what it does.
int init(const char* service_name)
{
w_service_name = get_service_name(service_name);
SERVICE_TABLE_ENTRY ServiceTable[] =
{
{w_service_name, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
{NULL, NULL}
};
if (StartServiceCtrlDispatcher(ServiceTable) == FALSE)
return GetLastError();
}
The Service.h header file is, naturally, a lot smaller:
#pragma once
#ifdef WINSERVICE_EXPORTS
#define WINSERVICE_API __declspec(dllexport)
#else
#define WINSERVICE_API __declspec(dllimport)
#endif
WINSERVICE_API int init(const char* service_name);
Just make sure you add WINSERVICE_EXPORTS to one of the definitions or replace it by the corresponding definition in your project.
Dart
I also needed to perform a few changes from the Dart side. Here's my prototype:
import 'dart:ffi' as ffi;
import 'dart:io';
import 'dart:isolate';
import 'package:ffi/ffi.dart';
import 'package:grpc/grpc.dart' as grpc;
// These two types represent the
// Init(...) function of the C API
typedef init_func = ffi.Int32 Function(ffi.Pointer<Utf8>);
typedef Init = int Function(ffi.Pointer<Utf8>);
// Entry point to the Dart application.
// When run as a Windows Service,
// this is still the entry point.
// This code is not embeded but is started
// as a regular console application.
void main() async {
final init = createInit();
// Starts the actual work in a separate Isolate
await Isolate.spawn(run, 'message');
final serviceName = Utf8.toUtf8('MProto_Server_from_Dart');
// calls the Init(...) function
var result = init(serviceName);
if (result != 0) return;
// blocks this Isolate indefinitely from continuing
while (true) {
sleep(Duration(days: 365));
}
}
// Creates the instance of the proxy to the Init(...)
// function.
Init createInit() {
final path =
r'[PATH to the C compiled DLL]';
final dylib = ffi.DynamicLibrary.open(path);
// ignore: omit_local_variable_types
final Init init =
dylib.lookup<ffi.NativeFunction<init_func>>('init').asFunction();
return init;
}
// Performs the actual work that needs to
// be done, in this case, we are hosting
// a gRPC service, but this should
// work with any other kind of
// payload, namely other types of
// http services.
void run(String message) async {
print('inside isolate');
var server = grpc.Server(
[
// my service classes
],
);
await server.serve(port: 5001);
}

There's no difference in using Dart for a Windows service as any other executable; you just need to call dart.exe with the correct arguments.
However, Windows doesn't support running arbitrary exes as Windows Services, as they require a little metadata/bootstrapping. I've had good experiences with NSSM - the Non-Sucking Service Manager. In the comments, SC.exe was suggested; but I was unable to get it running on the latest version of Windows Server :(

look at dart package dart_windows_service_support
He use dart:ffi and a dll file enables dart to run in Windows service mode
https://pub.dev/packages/dart_windows_service_support

Use WinSW
WinSW wraps and manages any application as a Windows service.
Create the service directory in your project.
Find the latest release of WinSW on GitHub, you are very likely looking specifically for WinSW-x64.exe. Copy this file under the service directory in your project and rename it to your linking, e.g. service\MyApp-Service.exe.
Create a configuration file for your service service\MyApp-Service.xml with the sample configuration below.
Run .\MyApp-Service.exe install from command line. Your service should be listed in Windows services.
Sample config XML:
<service>
<id>MyApp</id>
<name>My App</name>
<description>My App's description</description>
<executable>C:\tools\dart-sdk\bin\dart.exe</executable>
<workingdirectory>C:\path\to\project</workingdirectory>
<arguments>lib/main.dart</arguments>
<log mode="roll"></log>
<priority>high</priority>
</service>

Related

How do i run a Windows service in Azure Service Fabric?

I have a Windows service for test purposes that i want to migrate to Service Fabric. The service does nothing more than writing to a txt-file on my drive when it starts and when it stops. It works fine when i manually start and stop the service after installing it on my machine. Can i achieve the same result on service fabric or does the implementation be different?
I have created a guest executable with the service and deployed it to a local cluster following this guide.
First of all, I don't like this answer. After playing with it, I'm convinced the best way is to just port the code to a service fabric app. I would love to see a better "bolt-on" solution, but I haven't found any others. Every answer I've seen says "just run the exe as a Guest Executable", but a Windows Service exe doesn't "just run". It needs to be ran as a Windows Service which calls the OnStart entry point of the Service class (which inherits from ServiceBase).
The code below will allow your Windows Service to run in Service Fabric, but Service Fabric seems to report WARNINGS! So it's FAR from perfect.
It shouldn't require any changes to your OnStart or OnStop methods, however it does require some basic plumbing to work. This is also helpful if you wish to debug your windows services, as it allows you to pass in a /console command line argument and have it run in a console window.
First, either create your own ServiceBase class, or simply paste this code into your Service class (by default it's called Service1.cs in a C# Windows Service project):
// Expose public method to call the protected OnStart method
public void StartConsole(string[] args)
{
// Plumbing...
// Allocate a console, otherwise we can't properly terminate the console to call OnStop
AllocConsole();
// Yuck, better way?
StaticInstance = this;
// Handle CTRL+C, CTRL+BREAK, etc (call OnStop)
SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true);
// Start service code
this.OnStart(args);
}
// Expose public method to call protected OnStop method
public void StopConsole()
{
this.OnStop();
}
public static Service1 StaticInstance;
private static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
{
switch (ctrlType)
{
case CtrlTypes.CTRL_C_EVENT:
case CtrlTypes.CTRL_BREAK_EVENT:
case CtrlTypes.CTRL_CLOSE_EVENT:
case CtrlTypes.CTRL_LOGOFF_EVENT:
case CtrlTypes.CTRL_SHUTDOWN_EVENT:
StaticInstance.StopConsole();
return false;
}
return true;
}
[DllImport("kernel32.dll")]
private static extern bool AllocConsole();
[DllImport("Kernel32")]
public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);
public delegate bool HandlerRoutine(CtrlTypes CtrlType);
public enum CtrlTypes
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT,
CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT
}
Now change your Main method in Program.cs to look like this:
static void Main(string[] args)
{
var service = new Service1();
if (args.Length > 0 && args.Any(x => x.Equals("/console", StringComparison.OrdinalIgnoreCase)))
{
service.StartConsole(args);
}
else
{
ServiceBase.Run(
new ServiceBase[]
{
service
});
}
}
You may need to rename 'Service1' to whatever your service class is called.
When calling it through Service Fabric, make sure it's passing in the /console argument in ServiceManifest.xml:
<CodePackage Name="Code" Version="1.0.0">
<EntryPoint>
<ExeHost>
<Program>WindowsService1.exe</Program>
<Arguments>/console</Arguments>
<WorkingFolder>Work</WorkingFolder>
</ExeHost>
</EntryPoint>
</CodePackage>
If you wish to use this as a debuggable Windows Service, you can also set your 'Command line arguments' to /console under the Project settings > Debug tab.
EDIT:
A better option is to use TopShelf. This will work without warnings in Service Fabric, however it does require some code refactoring as it becomes a Console project instead of a Windows Service project.

FastCGI Handling multiple requests without a library

I would like to know how should I handle multiple requests with one instance of a program, by that I mean, a fcgi program is supposed to continue running after one request has been answered, the problem is, how do I know that the current request data inside the environment variables is not the one from the last request.
My idea is to use setenv to set the environment variables to NULL after parsing them so when they are not NULL it means that the server has set them to the values of the new request but I'm not sure if this is the way it is supposed to be done.
I know that there are libraries that handle this stuff and that it is safer to use those, but right now my objective is just to learn how fcgi works behind the libraries
It's not clear what do you mean by 'multiple requests' in your question.
Based on your description I assume that you expect that your FastCgi app is still alive after processing the first request and can handle another request.
But that's the nature of FastCgi: a single program/service is running in an 'infinite loop' and handle all incoming requests. It's guaranteed by the FastCGI design that the Request object (including all environment variables) are properly set.
The old CGI works in an opposite way: a new process (i.e. instance) of the CGI program is spawned on each request.
It's highly likely that you keen on concurrent requests. But that's still possible.
Unfortunately you haven't mentioned neither server type nor programming language nor OS which you work with.
It's really easy to find examples for handling concurrent requests on Unix systems in C/C++.
You've mentioned that you wouldn't like to use any libraries but I believe you have to use at least one which implements the FastCGI interface. The most commonly used is fcgiapp by Open Market.
Handling concurrent requests is achieved by the multi-threading technique which is called Locks.
I'm a 'Windows guy' so this is my example for WINAPI and C:
#define THREAD_COUNT 20
#define FAST_CGI_SOCKET ":9345"
#include <locale.h>
#include "fcgiapp.h"
CRITICAL_SECTION accept_mutex;
DWORD WINAPI requestHandler()
{
int code;
FCGX_Request request;
FCGX_InitRequest(&request, 0, 0);
for (;;)
{
EnterCriticalSection(&accept_mutex);
code = FCGX_Accept_r(&request);
LeaveCriticalSection(&accept_mutex);
if (code < 0) break;
// TODO handle request
FCGX_Finish_r(&request);
}
return 0;
}
void initFastCgi() {
FCGX_Init();
FCGX_OpenSocket(FAST_CGI_SOCKET, SOMAXCONN);
}
void startThreadsAndWait() {
int i;
HANDLE threads[THREAD_COUNT];
InitializeCriticalSection(&accept_mutex);
for (i = 0; i < THREAD_COUNT; i++) {
threads[i] = CreateThread(NULL, 0, &requestHandler, NULL, 0, NULL);
}
for (i = 0; i < THREAD_COUNT; i++) {
WaitForSingleObject(threads[i], INFINITE);
}
for (i = 0; i < THREAD_COUNT; i++) {
CloseHandle(threads[i]);
}
}
void appStart() {
setlocale(LC_ALL, "en_US.utf8");
initFastCgi();
}
void freeResources() {
}
void appFinish() {
freeResources();
}
int main(void)
{
appStart();
startThreadsAndWait();
appFinish();
return 0;
}
All the magic is around accept_mutex.
Hope that will help even if you use a different OS or a programming language

Is there a better way to "lock" a Port as a semaphore in Dart than this example?

Is it possible in Dart to “lock” a Port other than by starting a server on that Port. In other words I guess, the Port is acting as a semaphore. Alternatively is there another way to achieve the same result?
I posted a question asking for a solution to this problem, and Fox32 suggested starting a server on a specific Port, and in that way determine if another instance of the program is already running. I need to determine the first instance to start actual processing rather than whether actually just running, and that solution works.
While that solution works well, it appears to me that there should be a more tailored solution. Example code is below:
/*
* Attempt to connect to specific port to determine if first process.
*/
async.Future<bool> fTestIfFirstInstance() {
async.Completer<bool> oCompleter = new async.Completer<bool>();
const String S_HOST = "127.0.0.1"; // ie: localhost
const int I_PORT = 8087;
HttpServer.bind(S_HOST, I_PORT).then((oHtServer) {
ogHtServer = oHtServer; // copy to global
oCompleter.complete(true); // this is the first process
return;
}).catchError((oError) {
oCompleter.complete(false); // this is NOT the first process
return;
});
return oCompleter.future;
}
This is often done by using a file, e.g. '/tmp/my_program.lock' or '~/.my_program.lock' depending on global or per-user lock.
I dart in would be as simple as:
bool isRunning() {
return new File(lockPath).existsSync();
}
Starting:
void createLock() {
if (isRunning()) throw "Lock file '$lockPath' exists, program may be running";
new File(lockPath).createSync();
}
And when closing the program:
void deleteLock() {
new File(lockPath).deleteSync();
}
Something to remember is that while the HttpServer will be closed when the program closes, the file won't be deleted. This can be worked around by writing the programs PID to the lock file when creating the file, and check if the PID is alive in isRunning. If it's not alive, delete the file and return false.
I'm unsure whether this (RawServerSocket) is any "better" than the HttpServer solution, however perhaps it makes more sense.
I think that a means to simply "lock" the Port and unlock the Port would be worthwhile. It provides a good means of using a semaphore IMHO.
/*
* Attempt to connect to specific port to determine if first process.
*/
async.Future<bool> fTestIfFirstInstance() {
async.Completer<bool> oCompleter = new async.Completer<bool>();
RawServerSocket.bind("127.0.0.1", 8087).then((oSocket) {
ogSocket = oSocket; // assign to global
oCompleter.complete(true);
}).catchError((oError) {
oCompleter.complete(false);
});
return oCompleter.future;
}

Linux module: being notified about task creation and destruction

for Mach kernel API emulation on Linux, I need for my kernel module to get called when a task has been just created or is being terminated.
In my kernel module, this could most nicely be done via Linux Security Modules, but a couple of years ago, they prevented external modules from acting as a LSM by unexporting the needed symbols.
The only other way I could find was to make my module act like a rootkit. Find the syscall table and hook it in there.
Patching the kernel is out of the question. I need my app to be installed easily. Is there any other way?
You can use Kprobes, which enables you to dynamically hook into code in the kernel. You will need to find the right function among the ones involves in creating and destroying processes that give you the information you need. For instance, for tasks created, do_fork() in fork.c would be a good place to start. For tasks destroyed, do_exit. You would want to write a retprobe, which is a kind of kprobe that additionally gives you control at the end of the execution of the function, before it returns. The reason you want control before the function returns is to check if it succeeded in creating the process by checking the return value. If there was an error, then the function will return a negative value or in some cases possibly 0.
You would do this by creating a kretprobe struct:
static struct kretprobe do_fork_probe = {
.entry_handler = (kprobe_opcode_t *) my_do_fork_entry,
.handler = (kprobe_opcode_t *) my_do_fork_ret,
.maxactive = 20,
.data_size = sizeof(struct do_fork_ctx)
};
my_do_fork_entry gets executed when control enters the hooked function, and my_do_fork_ret gets executed just before it returns. You would hook it in as follows:
do_fork_probe.kp.addr =
(kprobe_opcode_t *) kallsyms_lookup_name("do_fork");
if ((ret = register_kretprobe(&do_fork_probe)) <0) {
// handle error
}
In the implementation of your hooks, it's a bit unwieldy to get the arguments and return value. You get these via the saved registers pt_regs data structure. Let's look at the return hook, where on x86 you get the return value via regs->ax.
static int my_do_fork_ret(struct kretprobe_instance *ri, struct pt_regs *regs)
{
struct do_fork_ctx *ctx = (struct do_fork_ctx *) ri->data;
int ret = regs->ax; // This is on x86
if (ret > 0) {
// It's not an error, probably a valid process
}
}
In the entry point, you can get access to the arguments via the registers. e.g. on x86, regs->di is the first argument, regs->si is the second etc. You can google to get the full list. Note that you shouldn't rely on these registers for the arguments in the return hook as the registers may have been overwritten for other computations.
You will surely have to jump many hoops in getting this working, but hopefully this note should set you off in the right direction.

C++ equivalent of .NET's Task.Delay?

I'm writing a C++/CX component to be consumed by Window's store Apps. I'm looking for a way to accomplish what Task.Delay(1000) does in C#.
Old Question, but still unanswered.
You can use
#include <chrono>
#include <thread>
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
This will need C++11, which shouldn't be a problem when using C++/CX.
After one year of using C++/CX, I have a general and reasonably correct answer to this question.
This link (from the Visual C++ Parallel Patterns Library documentation) includes a snippet for a function called complete_after(). That function creates a task that will complete after the specified number of milliseconds. You can then define a continuation task that will execute afterwards:
void MyFunction()
{
// ... Do a first thing ...
concurrency::create_task(complete_after(1000), concurrency::task_continuation_context::use_current)
.then([]() {
// Do the next thing, on the same thread.
});
}
Or better yet, if you use Visual C++'s coroutines capabilities simply type:
concurrency::task<void> MyFunctionAsync()
{
// ... Do a first thing ...
co_await complete_after(1000);
// Do the next thing.
// Warning: if not on the UI thread (e.g., on a threadpool thread), this may resume on a different thread.
}
You could create a concurrency::task, wait for 1000 time units and then call the ".then" method for the task. This will ensure that there is at least a wait of 1000 time units between the time you created the task and between the time it gets executed.
I'm not going to claim to be a wizard - I'm still fairly new to UWP and C++/CX., but what I'm using is the following:
public ref class MyClass sealed {
public:
MyClass()
{
m_timer = ref new Windows::UI::Xaml::DispatcherTimer;
m_timer->Tick += ref new Windows::Foundation::EventHandler<Platform::Object^>(this, &MyClass::PostDelay);
}
void StartDelay()
{
m_timer->Interval.Duration = 200 * 10000;// 200ms expressed in 100s of nanoseconds
m_timer->Start();
}
void PostDelay(Platform::Object^ sender, Platform::Object ^args)
{
m_timer->Stop();
// Do some stuff after the delay
}
private:
Windows::UI::Xaml::DispatcherTimer ^m_timer;
}
The main advantage over other approaches is that:
it's non-blocking
You're guaranteed to be called back on the XAML UI thread

Resources