Sco*_*own 5 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
Run Code Online (Sandbox Code Playgroud)
我们一直在使用“启动进程”来触发 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 }
Run Code Online (Sandbox Code Playgroud)
同样,没有errors.txt,也没有新的DLL。VB6.EXE 启动并就在那里。进程监视器在诊断可能存在的问题方面没有提供任何帮助。
这现在闻起来有安全门对我关闭的味道 - 即使同一个域用户正在运行相同的工作,不同之处在于这是一个后台进程......并且某些东西阻止了后台进程在相同的上下文中执行一个前台进程。
假设这个假设是正确的,有人可以指出远程触发(后台)会话无法运行 VB6.EXE 的原因吗?(当然,对于这种情况的解决方法将不胜感激:))
如果这不是安全问题 - 有人可以确定真正的罪魁祸首,以及让 VB6 作为后台进程运行的解决方案,就像我们习惯于看到它在 W2K8R2 上运行一样?
我参加聚会有点晚了,但这听起来与我刚刚遇到的情况非常相似。
当通过 Bamboo 在服务器上运行构建时,它会挂起。当登录构建服务器并手动运行构建时,它成功了。
削减代码后,我能够重现一个最小的失败案例。挂起是由 UserControl 的UserControl_Initialize
方法中操作 UI 控件的代码引起的,但仅限于该 UserControl 放置在同一项目中的 Form 上时。
在编译期间,编译器将创建 Form 的一个实例(为什么,我不知道),Form 又创建 UserControl 的实例,而 UserControl 又运行该UserControl_Initialize
方法。我只能假设此时运行代码会导致某种错误,并导致编译器挂起。
该事件也可能导致相同的错误UserControl_Resize
。Ambient.UserMode
通过在尝试调整子控件的大小之前检查是否为真,可以很容易地修复这种情况。
Private Sub UserControl_Resize()
If UserControl.Ambient.UserMode Then
' Position the child controls
End If
End Sub
Run Code Online (Sandbox Code Playgroud)
修复这些UserControl_Initialize
方法需要在不同的点运行这些方法中的代码(例如,当向 UserControl 提供要显示的数据时,我们现在运行之前在UserControl_Initialize
)。
另外值得注意的是我们必须使用的 VB6.exe 的兼容性设置。使用“Windows XP SP3”兼容模式导致 VB6.exe 立即挂起。我们必须将其设置为不使用任何兼容模式,但我们必须设置以管理员身份运行此程序,并将其应用于所有用户。