powershell - 从 powershell 超时 MS Access ComObject
问题描述
我有一个 powershell 脚本,它创建一个 MS Access ComObject 并使用它在 MS Access 数据库中运行一个宏,如下所示:
$AccessDb= 新对象 -ComObject Access.Application
try{
foreach($file in $Files)
{
...
$AccessDb.DoCmd.RunMacro('mcrScr')
...
}
}
catch { ... }
问题是当出现运行时错误时,MS Access 会在交互式窗口或对话框中抛出错误,这会导致 powershell 挂起;只是等待窗口关闭,因此其他 .mdb 文件的宏不会运行。我一直在尝试在线文章中的选项来超时我的这段代码 $AccessDb.DoCmd.RunMacro('mcrScr'),如果它运行超过 x 秒数。我使用了作业、运行空间和 [system.diagnostics.stopwatch],但没有成功。有没有更好的方法来做到这一点。我有点没有选择了。
编辑:@Paul,作为对您的评论的回应,我正在添加我如何使用运行空间来解决问题。
function Script-Timeout {
param([scriptblock]$Command,[int]$Timeout)
$Runspace = [runspacefactory]::CreateRunspace()
$Runspace.Open()
$PS = [powershell]::Create().AddScript($Command)
$PS.Runspace = $Runspace
$chk = $PS.BeginInvoke()
if($chk.AsyncWaitHandle.WaitOne($Timeout))
{
$PS.EndInvoke($chk)
}
else
{
throw "Command taking too long to run. Timeout exceeded."
$PS.EndInvoke($chk)
}
}
然后在运行 MS Acess 宏的脚本部分中使用 Script-Timeout 函数,如下所示:
Try{
forEach($mdbfile in Files)
{
...
Script-Timeout -Command {
$AccessDb= New-Object -ComObject Access.Application
$AccessDb.OpenCurrentDatabase($mdbfile)
$AccessDb.DoCmd.RunMacro('mcrUpdate')
$AccessDb.CloseCurrentDatabase()
} -Timeout 20
...
}
}
catch
{
#catch exception
}
我在 VBA 中人为地创建了一个运行时错误,它会引发一个错误对话框。这样,如果脚本的 RunMacro 部分运行,它将挂起 powershell。这是我希望运行空间在 x 秒后从 powershell 超时运行宏的地方。运行空间的问题是 MS Access 宏根本没有运行。在 powershell 调试模式下,我看到脚本超时函数的 if 块总是成功执行,无论是否存在人为运行时错误
解决方案
推荐阅读
- vue.js - Vue Js - 如何在加载数据后禁用所有输入
- android - 努力确定此 SecurityException 错误的原因 (Xamarin)
- sql - 雪花合并命令在 ON 子句返回无效标识符
- php - 找不到模板 Symfony 4
- homebrew - 使用 brew 在特定版本中安装 Helm
- domain-driven-design - DDD - 将实体存储在非主要基础设施中的域服务
- c++ - std::setw() 没有给出想要的结果
- c++ - 将文件加载到结构中
- java - 在 github 上设置 maven 工作流时,我不断收到此错误:“构建无法读取 1 个项目 - > [Help 1]”
- c - 我有 uint8_t 错误的问题,我无法 printf(integer)