2012-07-25 143 views
4

我在windows 7上的visual studio 2008中有一个C++项目,我尝试启动一项新服务。 我以管理员身份运行visual studio。 我无法启动服务(serviceMain甚至没有被调用)。Windows 7上的StartServiceCtrlDispatcher访问被拒绝

这是我的主要功能:

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

这是错误的:

wchar_t str[] = {'s','e','s','m'}; 

你忽略了终止NUL。使用

wchar_t str[] = L"sesm"; 
+0

嗨,我改变了它,我仍然得到同样的错误.. – lironda 2012-07-26 05:24:38

0

您是如何开始服务的?

即使您的用户位于管理员组中,程序也不会完全运行,除非您已经通过UAC,或者它们是从已提升的上下文启动的。如果您尝试通过Visual Studio进行调试,则可能需要右键单击Visual Studio,然后以管理员身份运行才能正常工作。

如果您希望能够从资源管理器启动服务,您需要在清单中将requestedExecutionLevel设置为'level = requireAdministrator'。从命令提示符启动将需要相同的,除非你使用'net start yourservice',当命令提示符将需要提升。从系统服务插件启动不需要特别准备,并且在Windows 7(不是Vista)下为MS签名的应用程序提供隐藏的提升。

2

如果您尝试从IDE(如Microsoft Visual Studio)或命令行启动Windows服务,则需要设置ConsoleHandler并手动调用ServiceStart(例如,

SetConsoleCtrlHandler(myConsoleHandler,TRUE);ServiceStart(argc,argv,TRUE);

在我们的应用程序中,我们传递了一个-debug标志,告诉应用程序作为控制台程序而不是Windows服务运行。

3

问题在于你在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)

0

一旦你完成代码,不要调试。 建立它。 当Build成功时,将在Debug内创建SessionMonitor.exe文件。 转到命令提示符并安装该服务。 SC打造“SESM” binPath =

围棋的“你SessionMonitor.exe \ SessionMonitor.exe的位置”来运行,键入services.msc 查找服务SESM,运行它,检查你在做了ServiceMain的作品。

1

StartServiceCtrlDispatcher access denied on windows 7

我相信这是在Windows中的一个错误。根据MSDN StartServiceCtrlDispatcher应该在失败时返回零,但是微软的某个人认为在API边界上抛出自定义(非C++)异常是一个好主意。

可以捕获并忽略此特殊类型的使用AddVectoredExceptionHandler要解决这个问题的异常:

#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);