我从.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()方法之前,如何获得服务状态结构的有效句柄?
答案 0 :(得分:0)
如果RegisterServiceCtrlHandlerEx函数(最有可能是ServiceUtil.RegisterServiceCtrlHandler
方法调用的函数)失败,它将返回空指针。
尝试调用GetLastError函数以获取有关错误的详细信息。我的猜测是,这是一个时间问题。在初始化期间,服务本身可能根本不准备接受处理程序函数。
你到底想要达到什么目的?我们或许能够找到不同的解决方案。