【问题标题】:WScript.Shell crashes ExcelWScript.Shell 使 Excel 崩溃
【发布时间】:2020-12-02 15:58:14
【问题描述】:

我正在使用 WshShell 从 Excel 中的 VBA 运行批处理文件。

  • 批处理文件非常简单,一行运行一个数字运算 程序。我可以直接运行批处理文件而不会出现问题。
  • 我正在使用 WshShell 或 WScript.Shell,因为我希望 VBA 等待加载 计算完成后返回 Excel 中的结果。
  • 我参考了“Microsoft Scripting Runtime”和“Windows Script Host Object Model”
  • 我已经使用相同的代码很长时间了。 它在 2-3 周前运行良好。现在它关闭了 Excel。如果我打开了一些电子表格,它会将它们全部关闭。
  • 我有两个版本,但它们都在“Set WinSh = ...”行崩溃。 Excel 不是 响应几(~10)秒,然后关闭。
  • 我正在使用 Office 365 MSO (16.0.12527.21294) 32 位。它由我的组织管理。
  • 我在 Word 中尝试了相同的代码,但它也崩溃了。

有人知道最近的更新是否可以做到这一点吗?还是我可以使用的其他方法?

潜艇是:

Public Sub RunBatch(FPath As String)
    Dim WinSh As Object
    Dim StrCmd As String
    Dim ErrCode As Long
    Set WinSh = New WshShell
    StrCmd = Chr(34) & FPath & Chr(34)
    ErrCode = WinSh.Run(StrCmd, WindowStyle:=1, WaitOnReturn:=True)
End Sub
  
Public Sub RunBatch2(FPath As String)
    Dim WinSh As Object
    Set WinSh = VBA.CreateObject("WScript.Shell")
    WinSh.Run FPath, 1, True
End Sub

【问题讨论】:

  • 我会做的是相反的事情:运行从 bat 文件中计算的数字,然后一直挂到完成,然后启动一个 vbscript 脚本,该脚本会打开 Excel 并运行宏。
  • 你可以用 win32: vbnet.mvps.org/index.html?code/faq/waitforsingleobject.htm (传递cmd.exe c:\your\bat\file.bat 作为命令行) - 你可以将当前代码临时移动到一个 .vbs 文件,看看它是否失败并显示错误消息你可以调查一下。
  • 感谢您的建议。我不能轻松地从批处理文件开始,因为它是 Excel 准备数据、保存 ascii 文件以进行数字运算然后运行它的较长过程的一部分。有趣的是,它曾经运行良好。我尝试了一个 .vbs 文件,它可以工作,但是当我将代码传输回 VBA 时,它再次崩溃。我可以在 VB.net 中重写整个 ting 并以这种方式控制 Excel,但这是几 1000 行 VBA 代码..... Marie
  • @MJ_Nadeau 在过去的 2-3 周内,您的机器上的某些配置可能发生了变化,您是否尝试过其他机器以查看行为是否相同?
  • @Lankymart 我们在 5 台计算机上进行了测试,其中 4 台使用 office 32 位,一台使用 office 64 位。所有人都表现出相同的行为,但它们都由同一组织管理。 WshShell (wshom.ocx) 的参考文件来自 2018 年。一项更改是 Windows 10 1809 的 2020-11 服务堆栈更新。我没有重新启动其中一台计算机,因此 2020-11 累积更新无法运行。在事件日志中没有我们可以追踪的事件。如果有人尝试不同的常规设置,但使用 win 10 1809.and office 365,我将不胜感激。

标签: excel vba wsh wscript.shell


【解决方案1】:

问题的根源是思科 AMP 安全策略的更新或更改。这会阻止使用 Windows 脚本宿主。我所在组织的安全部门正在努力寻找问题的解决方案。

与此同时,我找到了解决方法。我使用 shell(在恢复 VBA 代码之前不等待批处理结束)运行批处理,该批处理在进程结束时写入一个简单的文本文件,我等待文本文件以 1 秒的增量出现。它很粗糙,但到目前为止还有效。

Public Sub OneRunBatch()

Dim xlWB As Workbook
Dim fso1 As New FileSystemObject
Dim BatFile As Object
Dim IsDone As Boolean
Dim OutFileName As String
Dim DoneFileName As String
Dim OutPath As String
Dim DeleteBatFile As Boolean

Set xlWB = ThisWorkbook
OutPath = xlWB.Path
OutFileName = "HW.bat"
DoneFileName = "Done.txt"
DeleteBatFile = False

Set BatFile = fso1.CreateTextFile(OutPath & "\" & OutFileName)
BatFile.WriteLine "cd /d " & OutPath
BatFile.WriteLine "echo Hello World"
BatFile.WriteLine "dir > " & DoneFileName
BatFile.Close

IsDone = False
Call Shell(OutPath & "\" & OutFileName, vbNormalFocus)

Do Until IsDone
    If fso1.FileExists(OutPath & "\" & DoneFileName) Then IsDone = True
    Application.Wait (Now + TimeValue("00:00:01"))
Loop

fso1.DeleteFile (OutPath & "\" & DoneFileName)
If DeleteBatFile Then fso1.DeleteFile (OutPath & "\" & OutFileName)

End Sub

【讨论】:

    猜你喜欢
    • 2023-03-28
    • 2016-12-29
    • 1970-01-01
    • 2016-07-29
    • 1970-01-01
    • 1970-01-01
    • 2013-08-02
    • 1970-01-01
    • 2018-02-23
    相关资源
    最近更新 更多