c++ - 如何使用Windows API轻松控制Windows服务?

标签 c++ windows-services c++builder

问题

我想使用 Windows API 控制任何 Windows 服务,但我不能:(

= 我的“想要的解决方案”有什么问题?

当前解决方案

我使用的最丑陋但实用的方法如下(用于 Stop 命令):

void StopService()
{
    ShellExecute(Application->Handle,
                 "open",
                 "stop.bat",
                 NULL,
                 ExtractFilePath(Application->ExeName).c_str(),
                 SW_SHOW);
}

其中 stop.bat 是一个包含以下命令的 Windows 批处理文件:

::the command
sc stop "service name"
::a pause to see if something goes wrong
pause

必须关闭已启动的 cmd 窗口非常烦人...

想要解决方案

下面的函数似乎没问题。如果我尝试执行命令来停止不存在的服务,它会显示一条错误消息。但是当我尝试为现有服务运行它时,它运行了,但该服务没有任何反应(如果我命令停止它,它什么也不做)...

void ControlService(AnsiString ServiceName, DWORD Order)
{
    SC_HANDLE Scm, Svc;
    SERVICE_STATUS Status;

    Scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

    if(Scm != 0)
    {
        Svc = OpenService(Scm, PChar(ServiceName.c_str()), SERVICE_ALL_ACCESS);

        if(Svc != 0)
        {
            ControlService(Svc, Order, &Status);

            // handle Status....
            CloseServiceHandle(Svc);
        }
        else
        {
            ShowLastError();
        }
        CloseServiceHandle(Scm);
    }
    else
    {
        ShowLastError();
    }
}

void ShowLastError()
{
    LPVOID lpMsgBuf;

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        GetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPTSTR) &lpMsgBuf,
        0,
        NULL
    );

    // Display the string.
    MessageBox(NULL, (char*)lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION);

    // Free the buffer.
    LocalFree(lpMsgBuf);
}

怎么了????

最佳答案

您可能遇到的两个可能问题:

  1. 您检查服务状态的时间过早。 ServiceControl 立即返回,无需等待服务完成请求。您的服务可能会转换为 SERVICE_STOP_PENDING,在这种情况下,您必须给它一些时间并再次检查。
  2. 有处于运行状态的依赖服务。您将不得不枚举相关服务,先关闭它们,然后停止您的服务。

在#2 上,MSDN 上的示例代码有很好的解释.这是来自同一页面的引述:

However, if the SCM determines that other running services are dependent on the specified service, it will not forward the stop request. Instead, it returns ERROR_DEPENDENT_SERVICES_RUNNING. Therefore, to programmatically stop such a service, you must first enumerate and stop its dependent services.

关于c++ - 如何使用Windows API轻松控制Windows服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16898066/

相关文章:

c++ - 在 64 位系统上更大的指针有什么好处?

C++ 内存不足异常测试

c++ - atomic< T > 的算术运算符在哪里/如何定义?

c++ - 读取以 bigendian 编写的文件

c++ - 有一个 .exe 的路径,我怎么知道它是否正在运行?

运行安装包问题的 C# Windows 服务

windows - 为什么 boost::filesystem is_directory 在作为 Windows 服务运行时返回不同的结果?

c++ - 优化估计 Pi 函数 C++

当这些类使用某些对象时,C# Windows 会丢失对类库的引用吗?

c++ - 如何在 Borland C++ 中绘制实心圆?