Windows/Linux/Mac跨平台将前台进程以后台方式运行.
直接上代码:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include "daemon_wrapper.h"
//#include "dump_info.h"
#ifdef _MSC_VER
#include <windows.h>
#include <objbase.h>
#include <shellapi.h>
// #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") // no console window
#pragma comment(lib, "shell32.lib")
#else
#include <unistd.h>
#endif
void daemon_wrapper(const char *application, const char *parameters) {
#ifdef _MSC_VER
SHELLEXECUTEINFOA sei = {0};
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
sei.lpVerb = "open";
sei.lpFile = application;// application name
sei.lpParameters = parameters;//command line
sei.nShow = SW_HIDE;
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
ShellExecuteExA(&sei);
//ShellExecuteA(0, "open", exec, parameters, NULL, SW_HIDE);
Sleep(1000); // 1s
CoUninitialize();
exit(0);
#else
#if defined(__APPLE__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
(void)exec;
(void)parameters;
if(daemon(0, 0) == -1 && errno != 0) {
printf("failed to put the process in background: %s", strerror(errno));
} else {
// when in background, write log to a file
//log_to_file = 1;
}
#if defined(__APPLE__)
#pragma GCC diagnostic pop
#endif
#endif
}
测试例子代码:
#undef UNICODE
#undef _UNICODE
#include <windows.h>
#include <thread>
#include <daemon_wrapper.h>
void usage(const char* appName)
{
printf("usage: %s cmd_line [daemon]\n", appName);
}
int main(int argc, char** argv)
{
if (argc == 3)
{
if (strcmp(argv[2], "daemon") == 0)
{
daemon_wrapper(argv[0], argv[1]);
}
}
else if (argc == 2)
{
bool quit = false;
std::thread([&argv, &quit]()
{
while (quit == false)
{
printf("I am alive!");
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
).join();
}
else
{
usage("appdaemon");
}
return 0;
}