初始化服务后获取服务状态句柄

时间:2011-12-05 17:57:42

标签: winapi service interop .net-1.1

我从.Net 1.1调用Win32 API来请求服务的额外启动时间(.Net 2.0及以上版本当前不是一个选项)。这是我在OnStart()方法中调用的伪代码。

private void OnStart(){
    private IntPtr statusHandle;
    private IntPtr serviceHandle;
    private IntPtr serviceControlManagerHandle;

    serviceControlManagerHandle = ServiceUtil.OpenSCManager(null, null, (uint)ServiceUtil.SCM_ACCESS.SC_MANAGER_ALL_ACCESS);
    serviceHandle = ServiceUtil.OpenService(serviceControlManagerHandle, this.ServiceName, (uint)ServiceUtil.SERVICE_ACCESS.SERVICE_ALL_ACCESS);

    //This fills the empty object with VALID data
    SERVICE_STATUS status = ServiceUtil.QueryServiceStatus(serviceHandle, ref status)

    //This returns a VALID pointer.
    statusHandle = ServiceUtil.RegisterServiceCtrlHandler(this.ServiceName, serviceHandle);
}

这部分工作正常。我收到每个有效的(非IntPtr.Zero)句柄,我可以更新SERVICE_STATUS。但是,我真的需要这个代码在Init()方法中(我正在改进一个超时的遗留服务)。但是当我将此代码移动到Init()方法时,我可以获得服务控制管理器和服务本身的有效句柄,但不能获得服务状态。我得到的非工作代码如下所示......

private void MyServiceClass(){
    InitializeComponent();

    private IntPtr statusHandle;
    private IntPtr serviceHandle;
    private IntPtr serviceControlManagerHandle;

    serviceControlManagerHandle = ServiceUtil.OpenSCManager(null, null, (uint)ServiceUtil.SCM_ACCESS.SC_MANAGER_ALL_ACCESS);
    serviceHandle = ServiceUtil.OpenService(serviceControlManagerHandle, this.ServiceName, (uint)ServiceUtil.SERVICE_ACCESS.SERVICE_ALL_ACCESS);
    statusHandle = ServiceUtil.RegisterServiceCtrlHandler(this.ServiceName, serviceHandle);

    //This fills the empty object with VALID data
    SERVICE_STATUS status = ServiceUtil.QueryServiceStatus(serviceHandle, ref status)

    //This returns an INVALID pointer.
    statusHandle = ServiceUtil.RegisterServiceCtrlHandler(this.ServiceName, serviceHandle);
}

在两种情况下,QueryServiceStatus使用有效值填充“status”。但是,只有第一个示例将“statusHandle”设置为有效指针。在进入OnStart()方法之前,如何获得服务状态结构的有效句柄?

1 个答案:

答案 0 :(得分:0)

如果RegisterServiceCtrlHandlerEx函数(最有可能是ServiceUtil.RegisterServiceCtrlHandler方法调用的函数)失败,它将返回空指针

尝试调用GetLastError函数以获取有关错误的详细信息。我的猜测是,这是一个时间问题。在初始化期间,服务本身可能根本不准备接受处理程序函数

你到底想要达到什么目的?我们或许能够找到不同的解决方案。