在服务器2016上将VB6编译为后台进程

时间:2018-12-04 15:03:27

标签: vb6 background-process windows-server-2016

我们有一个非常奇怪的行为,无法确定根本原因。我们使用TFS(2017.U2)来编译旧系统,并正在尝试从2008R2到2016年更新我们的构建服务器场。构建系统使用PowerShell(v5)循环浏览VBP项目列表并运行VBS脚本以编译项目。

首先介绍一些基础知识。 UAC被完全禁用(在注册表中,不仅是滑块控件),VB6.EXE也被设置为与XP SP3兼容,并且还可以以管理员身份运行。

不幸的是,虽然我们可以看到VB6.EXE在任务管理器中启动-但它只是挂起。零活动。以交互方式运行相同的编译对于相同的用户来说效果很好。这使我从理论上讲这是一个环境问题,但是进程浏览器向我展示了VB6.EXE进程上的有效用户环境。

我不认为这是由于VB6引发错误所致,因为(至少在Windows Server的早期版本中)当后台进程打开UI元素时,操作系统向前台指示后台希望进入我们看不到。

我们已经将其存为一个最小的代码示例,我称之为“ test.ps1”:

$vb6="C:\Program Files (x86)\Microsoft Visual Studio\VB98\vb6.exe"
Set-Location D:\Builds\27\s\path\prjdir
start-process $vb6 -ArgumentList "/make /out errors.txt project.vbp"  -wait

我们一直在使用“启动过程”来触发VB6编译,因为通过PowerShell直接调用不能正确地摄取参数(它们实际上是在完整过程中传递到主脚本中的字符串构成的)。 ..这是简化版本)。

以交互方式运行(。\ test.ps1)时,此功能正常运行。该项目已编译,我得到了一个errors.txt文件。

当作为进程启动时(start-process。\ test.ps1),它再次正常运行。

通过TFS“ PowerShell脚本”任务触发时,此操作无法完成VB6步骤-可以在“任务”查看器中使用适当的参数查看VB6.EXE,并且没有CPU或IO与该任务相关联。没有写入errors.txt文件。没有创建新的DLL。

通过在另一台计算机上运行测试脚本,我甚至可以进一步简化这个过程,并从堆栈中删除TFS。我对该脚本进行了远程调用,并使用以下命令复制了结果:

PS C:\Users\svc_build> Invoke-Command –ComputerName TestBuild02 –ScriptBlock {powershell  C:\Users\svc_build\desktop\test.ps1 }

同样,没有errors.txt,也没有新的DLL。 VB6.EXE启动,然后坐在那里。进程监视器在诊断可能是问题方面没有提供任何帮助。

这现在闻起来像是一扇安全门正在关闭我-即使同一个域用户正在运行相同的工作,不同之处在于这是一个后台进程...并且某些原因阻止了后台进程在服务器中执行与前台进程相同的上下文。

假设此假设正确,那么有人可以指出远程触发(后台)会话无法运行VB6.EXE的原因吗? (当然,可以解决这种情况:))

如果这不是安全问题-有人可以找出真正的罪魁祸首,以及使VB6作为后台进程运行的解决方案,就像我们曾经看到它在W2K8R2上运行一样?

1 个答案:

答案 0 :(得分:0)

我参加聚会有点晚了,但这听起来与我刚刚遇到的情况非常相似。

  • Windows 10 v2004
  • 已禁用UAC
  • 通过PowerShell脚本运行VB6.exe进行编译。
  • 使用Bamboo作为构建服务器,以托管服务帐户的身份运行。

通过Bamboo在服务器上运行构建时,它将挂起。登录构建服务器并手动运行构建时,成功。

在减少代码之后,我能够重现最小的失败案例。挂起是由操作UI控件的UserControl UserControl_Initialize方法中的代码引起的,而当该UserControl放在同一项目中的Form上时,则是 only

在编译过程中,编译器将创建Form的实例(为什么,我不知道),该实例又创建UserControl的实例,后者又运行UserControl_Initialize方法。我只能假设在那时运行代码会导致某种错误,并导致编译器挂起。

UserControl_Resize事件可能导致相同的错误。通过在尝试调整子控件的大小之前检查Ambient.UserMode是否正确,可以很容易地解决这种情况。

Private Sub UserControl_Resize()
    If UserControl.Ambient.UserMode Then
        ' Position the child controls
    End If
End Sub

修复UserControl_Initialize方法后,这些方法中的代码必须在其他位置运行(例如,当UserControl得到要显示的数据时,我们现在运行以前在{{1 }}。

还值得注意的是我们必须使用的VB6.exe的兼容性设置。使用“ Windows XP SP3”兼容模式会导致VB6.exe立即挂起。我们必须将其设置为不使用任何兼容模式,但必须将以管理员身份运行该程序,并将其适用于所有用户。