MsgWaitForMultipleObjectsEx在VB6中返回87

时间:2014-01-27 15:19:01

标签: winapi service vb6

我目前正在VB6中为真正的遗留应用程序编写服务。 我的工作基于Sergey Merzlikin“NT服务样本”(http://www.smsoft.ru/en/ntservice.htm)。

直到今天我还使用了NTSVC.OCX,但它似乎无法在Windows Server核心上运行,因为它涉及ActiveX中的一个表单(我想)。

所以我跳到了完整的Winapi服务,主要是我遇到了问题:

MsgWaitforMultipleObjectsEx,它返回87(无效参数) 这个API似乎非常棘手。

原始代码使用MsgWaitForMultipleObjects,但导致MSVBVM60.dll中的应用程序崩溃(c0000005)。 测试平台:Windows 2012

我调整了相当多的声明,所以也许我做错了。 无论如何,这里是代码中最相关的部分:

Private Declare Function MsgWaitForMultipleObjectsEx Lib "user32" _
   (ByVal nCount As Long, pHandles As Long, _
    ByVal dwMilliseconds, _
    ByVal dwWakeMask As Long, _
    ByVal dwFlags As Long) As Long

Public Declare Function CreateEvent2 Lib "kernel32" Alias "CreateEventW" 
   (ByVal lpEventAttributes As Long, _ 
   ByVal bManualReset As Long, _
   ByVal bInitialState As Long, _
   ByVal lpName As String) As Long

hStopEvent = CreateEvent2(0&, 1&, 0&, vbNullString)
hStopPendingEvent = CreateEvent2(0&, 1&, 0&, vbNullString)
hStartEvent = CreateEvent2(0&, 1&, 0&, vbNullString)
ServiceNamePtr = StrPtr(Service_Name)

我检查了句柄值,它们似乎没问题,但我怀疑它们没有“SYNCHRONIZE”的安全描述符 http://msdn.microsoft.com/en-us/library/windows/desktop/aa379607%28v=vs.85%29.aspx

然后在示例NT服务中有一个名为MsgWaitObj的包装器。这是我用以下内容替换MsgWaitForMultipleObjects的地方:

MsgWaitForMultipleObjectsEx(nObj, hObj, T1, QS_ALLEVENTS, 0&)

包装函数声明是:

Public Function MsgWaitObj(ByVal Interval As Long, _
        Optional ByRef hObj As Long, _
        Optional ByVal nObj As Long = 0&) As Long

Main中MsgWaitObj的外部声明和传递的引用如下:

hnd = NTService.StartAsService
h(0) = hnd
h(1) = hStartEvent
j(0) = hStopPendingEvent

<...>

IsNTService = MsgWaitObj(INFINITE, h(0), 2&)

<...>

Do

tm = MsgWaitObj(5000&, j(0), 1&)

Loop While tm = WAIT_TIMEOUT

我希望发布代码摘录是足够的,如果不是,我认为最简单的方法是下载ntservice示例并找出出错的地方,以及我是否在正确的道路上。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我测试了谢尔盖Merzlikin的示例应用程序从“使用VB6 / VB5编写NT服务”一文中引用的问题,并观察到了截然不同的行为。详细信息如下,但我的猜测是服务器核心安装不支持VB6应用程序。

带有完整GUI的Windows 2012

示例Windows服务SvSample.exe在完全安装Windows 2012时运行良好,完整的GUI没有应用配置更改。

具有最小服务器接口的Windows 2012

然后我通过这个PowerShell命令从完整的GUI转到最小的界面:Uninstall-WindowsFeature -Name Server-Gui-Shell –Restart。之后,样本服务 仍然没有明显问题。

Windows 2012 Server Core

然后我用Uninstall-WindowsFeature -Name Server-Gui-Mgmt-Infra –Restart删除剩余的位。完成配置并重新启动服务器后,我仔细检查是否仍然安装了ServerCore-WOW64功能(没有它,没有32位应用程序可以正常工作)。

此时样本服务确实停止工作。虽然不是msvbvm60.dll中的崩溃,而是服务控制管理器直截了当地报告(如系统事件日志中所示):

  

等待时间达到超时(30000毫秒)   示例VB6服务服务进行连接。

     

由于以下错误,示例VB6服务服务无法启动:
  该服务未及时响应启动或控制请求。

事实上,msvbvm60.dll中甚至不存在C:\Windows\SysWOW64\

结论

服务器核心(与一般的Windows 2012相反)根本不支持VB6运行时。我没有检查,但我很确定Windows 2008 R2 Server Core的情况也是如此。