我在Windows 7上的visual studio 2008中有一个c ++项目,我尝试启动一项新服务。 我以管理员身份运行visual studio。 我无法启动服务(甚至没有调用serviceMain)。
这是我的主要功能:
wchar_t str[] = {'s','e','s','m'};
int _tmain(int argc, _TCHAR* argv[])
{
SERVICE_TABLE_ENTRY dispTable[] =
{
{(wchar_t*)str, ServiceWork::ServiceMain},
{NULL, NULL}
};
int i = StartServiceCtrlDispatcher(dispTable);
int j = GetLastError();
return 0;
}
输出是:
。 。
'SessionMonitor.exe':已加载'C:\ Windows \ SysWOW64 \ cryptbase.dll'
'SessionMonitor.exe':已加载'C:\ Windows \ SysWOW64 \ imm32.dll'
'SessionMonitor.exe':已加载'C:\ Windows \ SysWOW64 \ msctf.dll'
SessionMonitor.exe中0x7638b9bc的第一次机会异常:0x00000005:访问被拒绝。 线程'Win32 Thread'(0x129c)已退出,代码为0(0x0)。 程序'[2492] SessionMonitor.exe:Native'已退出,代码为0(0x0)。
在调试时,j是1063 - ERROR_FAILED_SERVICE_CONTROLLER_CONNECT
以前有人遇到过这个问题吗? 任何解决方案?
谢谢你, Liron答案 0 :(得分:5)
问题在于您在visual studio中启动服务。
这不可能。您必须使用visual studio编译服务,然后使用sc命令(或按照here描述的程序)在命令提示符上注册它。所有正确的方法都在this问题的接受答案中描述。
如果要调试服务代码,则必须直接发出ServiceMain,例如:
int _tmain(int argc, _TCHAR* argv[])
{
#ifdef AS_SERVICE
SERVICE_TABLE_ENTRY dispTable[] =
{
{(wchar_t*)str, ServiceWork::ServiceMain},
{NULL, NULL}
};
int i = StartServiceCtrlDispatcher(dispTable);
int j = GetLastError();
return 0;
#else
ServiceMain(argc, argv);
#endif
}
当StartServiceCtrlDispatcher
失败并且GetLastError
返回ERROR_FAILED_SERVICE_CONTROLLER_CONNECT (1063)
答案 1 :(得分:2)
如果您尝试从Microsoft Visual Studio等IDE或命令行启动Windows服务,则需要设置ConsoleHandler并手动调用ServiceStart,例如。
SetConsoleCtrlHandler(myConsoleHandler,TRUE); ServiceStart(argc,argv,TRUE);
在我们的应用程序中,我们传递一个-debug标志,告诉应用程序作为控制台程序而不是Windows服务运行。
答案 2 :(得分:1)
StartServiceCtrlDispatcher access denied on windows 7
我相信这是Windows中的一个错误。根据{{3}},失败时应该返回零,但微软的某个人认为在API边界上抛出自定义(非C ++)异常是一个好主意。
您可以使用MSDN StartServiceCtrlDispatcher来捕获并忽略此特殊类型的异常,以解决此问题:
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
LONG WINAPI handle_exception(EXCEPTION_POINTERS* exception_data)
{
switch (exception_data->ExceptionRecord->ExceptionCode)
{
case 0x00000005: // thrown by StartServiceCtrlDispatcher for fun.
// Ignore these specific type of exceptions and continue execution.
// Note: There are several more interesting exceptions to catch here,
// which are out of scope of this question.
return EXCEPTION_CONTINUE_SEARCH;
case 0xE06D7363: // C++ exception code.
default:
// Pass all other type of exceptions to their regular exception handlers.
return EXCEPTION_EXECUTE_HANDLER;
}
}
auto handle = AddVectoredExceptionHandler(1, &handle_exception);
// Your code here. Now you can check for the return value of
// StartServiceCtrlDispatcher to see whether the application
// was started as a service or not without crashing.
RemoveVectoredExceptionHandler(handle);
答案 3 :(得分:0)
这是错误的:
wchar_t str[] = {'s','e','s','m'};
你遗漏了NUL的终止。使用
wchar_t str[] = L"sesm";
答案 4 :(得分:0)
你是如何开始服务的?
即使您的用户位于Administrators组中,在您通过UAC之前,程序也不会完全升级,或者它们是从已经提升的上下文启动的。如果您尝试通过Visual Studio进行调试,则可能需要右键单击Visual Studio并以管理员身份运行它以使其正常工作。
如果您希望能够从资源管理器启动服务,则需要在清单中将requestedExecutionLevel设置为“level = requireAdministrator”。从命令提示符启动将需要相同,除非您使用'net start yourservice',当需要提升命令提示符时。从系统服务插件启动不需要特别准备,并且在Windows 7(而不是Vista)下对MS签名应用程序进行隐藏的提升。
答案 5 :(得分:0)
完成代码后,请不要调试。 建立它。 当Build成功时,将在Debug内部创建SessionMonitor.exe文件。 转到命令提示符并安装该服务。 sc创建“sesm”binPath =“SessionMonitor.exe \ SessionMonitor.exe的位置”
转到“运行”并键入services.msc 找到服务sesm,运行它,检查你在ServiceMain中做了什么。