我编写了一个简单的Windows服务,将内存信息写入文本文件:
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <string>
using namespace std;
#define SLEEP_TIME 5000
#define LOGFILE "C:\\MyServices\\memstatus.txt"
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
void ServiceMain(int argc, char** argv);
void ControlHandler(DWORD request);
int InitService();
int WriteToLog(string file_name, string input)
{
FILE *f;
fopen_s(&f, file_name.c_str(), "a+");
fprintf(f, "%s\n", input.c_str());
fclose(f);
return 0;
}
string N = "MemoryStatus";
LPWSTR Name = new wchar_t(N.size() + 1);
int main()
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = Name;
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
// Start the control dispatcher thread for our service
StartServiceCtrlDispatcher(ServiceTable);
return 0;
}
void ServiceMain(int argc, char** argv)
{
int error;
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hStatus = RegisterServiceCtrlHandler(
Name,
(LPHANDLER_FUNCTION)ControlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0)
{
// Registering Control Handler failed
return;
}
// Initialize Service
error = InitService();
if (error)
{
// Initialization failed
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
// We report the running status to SCM.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hStatus, &ServiceStatus);
MEMORYSTATUS memory;
// The worker loop of a service
while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
{
char buffer[16];
GlobalMemoryStatus(&memory);
sprintf_s(buffer, "%d", memory.dwAvailPhys);
int result = WriteToLog("TestFile.txt", buffer);
if (result)
{
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
Sleep(SLEEP_TIME);
}
return;
}
// Service initialization
int InitService()
{
int result;
result = WriteToLog("TestFile.txt", "Monitoring started.");
return(result);
}
// Control handler function
void ControlHandler(DWORD request)
{
switch (request)
{
case SERVICE_CONTROL_STOP:
WriteToLog("TestFile.txt", "Monitoring stopped.");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &ServiceStatus);
return;
case SERVICE_CONTROL_SHUTDOWN:
WriteToLog("TestFile.txt", "Monitoring stopped.");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &ServiceStatus);
return;
default:
break;
}
// Report current status
SetServiceStatus(hStatus, &ServiceStatus);
return;
}我成功安装了它,但是任务管理器显示它的状态为已停止。当我右键单击并按下开始按钮时,我得到一个错误,系统找不到指定的文件。
我在StackOverflow或其他任何地方跟踪的几乎所有示例都得到了相同的错误。
发布于 2018-04-27 03:13:35
如果函数没有指定调用约定(与您的一样),除非配置了不同的默认值,否则大多数C++编译器都默认使用__cdecl调用约定。但是,Win32应用编程接口使用__stdcall调用约定。您需要将调用约定添加到您提供给服务API的函数的声明中。您还需要确保这些相同的函数也使用了正确的参数类型(您的参数类型不正确)。
摆脱那些对你隐藏编译器错误的类型转换。编译器抱怨是有原因的,不要忽视它。
试试这个:
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <string>
#include <fstream>
using namespace std;
#define SLEEP_TIME 5000
#define LOGFILE "C:\\MyServices\\memstatus.txt"
SERVICE_STATUS ServiceStatus = {};
SERVICE_STATUS_HANDLE hStatus = NULL;
void WINAPI ServiceMain(DWORD argc, LPTSTR* argv);
void WINAPI ControlHandler(DWORD request);
bool InitService();
bool WriteToLog(const string &file_name, const string &input)
{
ofstream f(file_name.c_str(), ios_base::app);
if (f.is_open())
f << input << "\n";
return !f.fail();
}
LPCTSTR Name = TEXT("MemoryStatus");
int main()
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = Name;
ServiceTable[0].lpServiceProc = &ServiceMain;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
// Start the control dispatcher thread for our service
StartServiceCtrlDispatcher(ServiceTable);
return 0;
}
void WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
{
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hStatus = RegisterServiceCtrlHandler(Name, &ControlHandler);
if (!hStatus)
{
// Registering Control Handler failed
return;
}
// Initialize Service
if (!InitService())
{
// Initialization failed
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
// We report the running status to SCM.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hStatus, &ServiceStatus);
MEMORYSTATUS memory;
// The worker loop of a service
while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
{
char buffer[16];
GlobalMemoryStatus(&memory);
sprintf_s(buffer, "%d", memory.dwAvailPhys);
if (!WriteToLog("TestFile.txt", buffer))
{
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
Sleep(SLEEP_TIME);
}
}
// Service initialization
bool InitService()
{
return WriteToLog("TestFile.txt", "Monitoring started.");
}
// Control handler function
void WINAPI ControlHandler(DWORD request)
{
switch (request)
{
case SERVICE_CONTROL_STOP:
WriteToLog("TestFile.txt", "Monitoring stopped.");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
break;
case SERVICE_CONTROL_SHUTDOWN:
WriteToLog("TestFile.txt", "Monitoring stopped.");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
break;
}
// Report current status
SetServiceStatus(hStatus, &ServiceStatus);
}
}我建议您阅读Microsoft的文档,了解如何正确编写服务:
也就是说,你说你的服务无法启动,因为Windows声称它找不到文件。这意味着您可能没有正确地将服务安装到SCM中。但是您没有显示要传递给sc.exe的实际命令行。确保您传递的EXE值是服务binPath的正确路径。
如果您确定是,则另一种可能是您的EXE依赖于不在Windows搜索路径上的外部DLL。这也可能导致您的EXE无法运行,并出现“找不到文件”错误。
我建议您在尝试启动服务时运行SysInternals Process Monitor。当错误发生时,这将确切地告诉你Windows正在寻找哪个文件。这将为您提供更好的线索,告诉您在何处需要对安装进行故障排除。
顺便说一句,Windows内置了对日志的支持。您不需要手动将日志消息写入文本文件。考虑使用ReportEvent()、EventWrite()等函数将消息记录到标准的Windows事件查看器中。
发布于 2018-04-27 15:34:19
你可以尝试一些方法来排除故障-
1.以下注册表位置中的服务映像路径是什么- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\YourServiceName\ImagePath 2.通过提供服务可执行文件的完全限定路径进行检查。
https://stackoverflow.com/questions/50042985
复制相似问题