简体   繁体   English

Windows 7上的StartServiceCtrlDispatcher访问被拒绝

[英]StartServiceCtrlDispatcher access denied on windows 7

I have a c++ project in visual studio 2008 on windows 7 where I try to start a new service. 我在Windows 7上的visual studio 2008中有一个c ++项目,我尝试启动一项新服务。 I'm running visual studio as administrator. 我以管理员身份运行visual studio。 I cant start the service (serviceMain is not even called). 我无法启动服务(甚至没有调用serviceMain)。

this is my main function: 这是我的主要功能:

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; 
}

the output is: 输出是:

. . .

'SessionMonitor.exe': Loaded 'C:\\Windows\\SysWOW64\\cryptbase.dll' 'SessionMonitor.exe':已加载'C:\\ Windows \\ SysWOW64 \\ cryptbase.dll'

'SessionMonitor.exe': Loaded 'C:\\Windows\\SysWOW64\\imm32.dll' 'SessionMonitor.exe':已加载'C:\\ Windows \\ SysWOW64 \\ imm32.dll'

'SessionMonitor.exe': Loaded 'C:\\Windows\\SysWOW64\\msctf.dll' 'SessionMonitor.exe':已加载'C:\\ Windows \\ SysWOW64 \\ msctf.dll'

First-chance exception at 0x7638b9bc in SessionMonitor.exe: 0x00000005: Access is denied. SessionMonitor.exe中0x7638b9bc的第一次机会异常:0x00000005:访问被拒绝。 The thread 'Win32 Thread' (0x129c) has exited with code 0 (0x0). 线程'Win32 Thread'(0x129c)已退出,代码为0(0x0)。 The program '[2492] SessionMonitor.exe: Native' has exited with code 0 (0x0). 程序'[2492] SessionMonitor.exe:Native'已退出,代码为0(0x0)。

on debug, j is 1063 - ERROR_FAILED_SERVICE_CONTROLLER_CONNECT 在调试时,j是1063 - ERROR_FAILED_SERVICE_CONTROLLER_CONNECT

does anyone encountered this problem before? 以前有人遇到过这个问题吗? any solution? 任何解决方案

thank you, Liron 谢谢你,Liron

The problem lies in the fact that you are launching the service inside visual studio. 问题在于您在visual studio中启动服务。

This cannot be done. 这是不可能做到的。 You have to just compile the service with visual studio and then register it on the command prompt by using sc command (or programmarically as described here ). 您必须使用visual studio编译服务,然后使用sc命令(或此处描述的programmarically)在命令提示符上注册它。 All the correct way is described in the accepted answer of this question. 所有正确的方法都在这个问题的公认答案中描述。

If you wish to debug the service code, you must issue the ServiceMain directly, for example: 如果要调试服务代码,则必须直接发出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
}

The same problem can show up also when StartServiceCtrlDispatcher fails and GetLastError returns ERROR_FAILED_SERVICE_CONTROLLER_CONNECT (1063) StartServiceCtrlDispatcher失败并且GetLastError返回ERROR_FAILED_SERVICE_CONTROLLER_CONNECT (1063)时,同样的问题也会出现

If you're trying to start a Windows service from an IDE like Microsoft Visual Studio or from a command line, then you'll need to setup a ConsoleHandler and call ServiceStart manaully eg 如果您尝试从Microsoft Visual Studio等IDE或命令行启动Windows服务,则需要设置ConsoleHandler并以manaully调用ServiceStart,例如

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

In our app, we pass a -debug flag which tells the app to run as a console program not a Windows service. 在我们的应用程序中,我们传递一个-debug标志,告诉应用程序作为控制台程序而不是Windows服务运行。

StartServiceCtrlDispatcher access denied on windows 7 Windows 7上的StartServiceCtrlDispatcher访问被拒绝

I believe this is a bug in Windows. 我相信这是Windows中的一个错误。 According to MSDN StartServiceCtrlDispatcher should return zero on failure, but someone at Microsoft thought it would be a great idea to throw a custom (non-C++) exception across API boundaries instead. 根据MSDN,StartServiceCtrlDispatcher应该在失败时返回零,但是微软的某个人认为在API边界之间抛出自定义(非C ++)异常是一个好主意。

You can catch and ignore this special type of exception using AddVectoredExceptionHandler to workaround the problem: 您可以使用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);

This is wrong: 这是错的:

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

You've left out the terminating NUL. 你遗漏了NUL的终止。 Use 使用

wchar_t str[] = L"sesm";

How are you starting the service? 你是如何开始服务的?

Even with your user in the Administrators group, programs won't run fully elevated until you've been through UAC, or they're launched from an already-elevated context. 即使您的用户位于Administrators组中,在您通过UAC之前,程序也不会完全升级,或者它们是从已经提升的上下文启动的。 If you're trying to debug through Visual Studio, you may need to right-click on Visual Studio and run it as Administrator for it to work. 如果您尝试通过Visual Studio进行调试,则可能需要右键单击Visual Studio并以管理员身份运行它以使其正常工作。

If you want to be able to launch the service from Explorer you'll need to set the requestedExecutionLevel to 'level=requireAdministrator' in the manifest. 如果您希望能够从资源管理器启动服务,则需要在清单中将requestedExecutionLevel设置为“level = requireAdministrator”。 Launching from Command Prompt will need the same, except if you're using 'net start yourservice', when the Command Prompt will need to be elevated. 从命令提示符启动将需要相同,除非您使用'net start yourservice',当需要提升命令提示符时。 Launching from the system services plugin requires no special preparation, and has a hidden elevation boost for MS signed apps under Windows 7 (not Vista). 从系统服务插件启动不需要特别准备,并且在Windows 7(而不是Vista)下对MS签名应用程序具有隐藏的提升。

Once you finish the code, don't debug. 完成代码后,请不要调试。 Build it. 建立它。 When Build succeeds, SessionMonitor.exe file will be created inside Debug. 当Build成功时,将在Debug内部创建SessionMonitor.exe文件。 Go to command prompt and install the service. 转到命令提示符并安装该服务。 sc create "sesm" binPath= "the location of your SessionMonitor.exe\\SessionMonitor.exe" sc创建“sesm”binPath =“SessionMonitor.exe \\ SessionMonitor.exe的位置”

The go to Run and type services.msc Find the service sesm, Run it, Check if what you have done in the ServiceMain works. 转到运行并键入services.msc找到服务sesm,运行它,检查您在ServiceMain中所做的工作是否正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM