Windows VB6 的 8 权限破坏 Shell 调用

Windows 8 permission havoc on VB6 Shell Call

我正在尝试调用命令提示符将文本文件复制到用 VB6 编写的已编译 OCX 中的端口。它通过命令提示符中的复制命令执行此操作,将文本文件发送到 "LPT1" 等端口。这在 XP 和 7 上运行良好,但 Windows 8 不允许它发生。我已采取以下步骤:

由于该命令在 Windows XP 和 7 上都有效,我倾向于认为这是 Windows 8 的权限问题,但到目前为止所有解决方法都失败了。如果需要更多信息,请告诉我,我会提供。谢谢!

编辑:我发现 OCX 在调试时表现正常...我的猜测是 OCX 的调试授予它 IDE 拥有的特权,即 Visual Studio 6.

编辑:根据要求,这是用 VB6 编写的原始 ShellAndWait 代码,用于启动 cmd 控制台。

Public Function ShellAndWait(ByVal FilePath As String, ByVal eAppStyle As VbAppWinStyle) As Boolean
Dim lPID As Long

     'Default to not found'
      m_lShellHandle = 0
     'run the program'
     lPID = Shell(FilePath, eAppStyle)
     ' Check for errors'
     If lPID = 0 Then
       ShellAndWait = False
       Exit Function
     End If

    'The command console window is tough to get a hold of, so'
    'that's the reason there are two attempts before moving on'
    'and the delays, allow time for window to start'
    DoEvents
    Sleep 500

    'Find the window handle'
    EnumWindows AddressOf FindThread, lPID
     'Not found - Try finding again (more aggressive wait)'
     If m_lShellHandle = 0 Then
        Sleep (1000)
        EnumWindows AddressOf FindThread, lPID
    End If
    'Make sure we have a valid window'
    If m_lShellHandle <> 0 Then
        'Keep checking to see if window is still available'
        Do While IsWindow(m_lShellHandle)
             'Allow repaint'
             DoEvents
            'Allow other processes to run'
            SleepEx 300, True
        Loop
    End If

    ShellAndWait = True
End Function

您发布的代码提供了答案,问题是对 EnumWindows 的调用。 VB6 没有可用的 64 位编译器,任何 VB6 应用程序都将声明 EnumWindows 函数,类似于:

Declare Function EnumWindows Lib "user32.dll" (ByVal lpEnumFunc As _
Long, ByVal lParam As Long) As Long 

问题是第一个参数是回调的函数指针,Long是32位的内存地址,AddressOf运算符只会return32位的回调地址。据我所知,在 VB6 中没有真正的方法来声明一个 API 函数来接受 64 位指针。事实上,如上面的评论所述,64 位 Office 需要对 VBA 运行时进行扩展,以允许对 64 位安全的 API 调用使用 LongPtr 类型和 PtrSafe 声明。您将在问题 'Can a VB6 component be compiled to 64 bit?' and the Office Dev Center page for PtrSafe.

中找到更多相关信息

在调试器的上下文中可能 运行 没问题,因为它在 WOW 环境中 运行,但如果从另一个上下文调用会失败,因为它会尝试在非 WOW 上下文。

虽然 可能 有一些解决方法,但它会涉及去除绝大多数本机 API 调用。正如评论所说,"The command console window is tough to get a hold of, so..." 将其移植到 .NET 可能会更容易。