如何从Powershell调用.exe时阻止“Program has stopped working”对话框
我正在使用PS脚本生成大量Crystal Reports(Windows 7)的.xml表示形式。在这个脚本中,我创建了一个代表所有需要解析的文件的对象,然后遍历它们,逐个调用一个.exe文件。偶尔,这个.exe崩溃。这很好,因为它很罕见,无法处理的报告可以手动标记和检查。问题是我有成千上万的.rpt文件需要处理,当.exe崩溃时,Windows会弹出一个对话框,要求进行调试或继续。如何从Powershell调用.exe时阻止“Program has stopped working”对话框
事情我为了解决这个问题,曾尝试:
HKEY_CURRENT_USER \ SOFTWARE \微软\的Windows \ Windows错误报告\ DebugApplications:我在这里把我的exe文件名,并设置值为0(不调试)
HKEY_LOCAL_MACHINE \ SOFTWARE \微软\的Windows \ Windows错误报告\ DebugApplications:同上
设置调用EXE为SilentlyContinue循环
关闭错误报告如下:控制面板>操作中心>更改操作中心设置>问题报告设置>为所有用户更改报表设置>“从不检查解决方案”>确定>确定(这只是禁用‘Windows可以在网上查询...’对话框)
不过,我得到了弹出窗口。还有另一个注册表项,完全禁用了“程序已停止工作”UI,但我不想这样做,因为作为其他应用程序的开发人员,我需要知道什么时候出现问题。我只是想排除这个脚本或它从显示UI所调用的exe。
如果我可以这样做,那么脚本可以无人值守运行。
错误的.exe是最新的二进制发布:https://github.com/ajryan/RptToXml,并且在报告文件中遇到空字节时似乎失败。
这里是我的代码:
[xml]$MainConfigFile = Get-Content "settings.config.xml"
[xml]$SSRSConfigFile = Get-Content "ssrs.config.xml"
[xml]$CrystalConfigFile = Get-Content "crystal.config.xml"
# create settings objects from xml objects
$MainSettings = @{
OutputPath = $MainConfigFile.Settings.OutputPath
SearchString = $MainConfigFile.Settings.SearchString
ParseCrystal = $MainConfigFile.Settings.ParseCrystal
ParseSSRS = $MainConfigFile.Settings.ParseSSRS
}
$CrystalSettings = @{
InputFolderPath = $CrystalConfigFile.CrystalSettings.InputFolderPath
ContinueOnError = $CrystalConfigFile.CrystalSettings.ContinueOnError
}
$RsSettings = @{
ReportServerUri = $SSRSConfigFile.RsSettings.ReportServerUri
RsVersion = $SSRSConfigFile.RsSettings.RsVersion
}
Clear
Write-Host "Ensure these settings are correct before you proceed:" -ForegroundColor Yellow
Write-Host ""
Write-Host "Main Settings" -ForegroundColor Green
$MainSettings
Write-Host ""
Write-Host "Crystal Settings" -ForegroundColor Green
$CrystalSettings
Write-Host ""
Write-Host "SSRS Settings" -ForegroundColor Green
$RsSettings
Write-Host ""
# user must confirm
[string]$SettingsOK=(Read-Host "[Y] to proceed, [N] to quit:")
if ($SettingsOK -ne "Y") {exit}
Write-Host ""
Write-Host "______________________________________"
Clear
# is the output path syntax valid?
if (!(Test-Path -Path $MainSettings.OutputPath -IsValid)) {
Write-Host -ForegroundColor Green "Output path syntax is invalid:" $MainSettings.OutputPath
exit
} else {
Write-Host -ForegroundColor Green "Output path syntax is correct:" $MainSettings.OutputPath
}
# does the output path exist?
if (!(Test-Path -Path $MainSettings.OutputPath)) {
Write-Host -ForegroundColor Yellow "Output path does not exist:" $MainSettings.OutputPath
[string]$CreateOutputPathOK=(Read-Host "[Y] to create the directory, [N] to quit.")
if ($CreateOutputPathOK -ne "Y") {exit} else {New-Item -Path $MainSettings.OutputPath -ItemType Directory}
} else {
Write-Host -ForegroundColor Green "Output path already exists:" $MainSettings.OutputPath
}
Write-Host ""
Write-Host "______________________________________"
Clear
# get all .rpt files in the input folder, recursively
$CrystalFiles=Get-ChildItem -Path $CrystalSettings.InputFolderPath -Include "*.rpt" -Recurse
Write-Host ""
# count files first and ask the user if they want to see the output, otherwise proceed
Write-Host -ForegroundColor Yellow $CrystalFiles.Count ".rpt files were found in" $CrystalSettings.InputFolderPath
[string]$ShowFilesOK=(Read-Host "[Enter] to proceed, [Y] to view the list of files in the directory, [N] to quit.")
if ($ShowFilesOK -eq "Y") {
Clear
# loop through the collection of files and display the file path of each one
$CrystalFiles | ForEach-Object -Process {$_.FullName.TrimStart($CrystalSettings.InputFolderPath)}
Write-Host "______________________________________"
# user must confirm
Write-Host ""
Write-Host -ForegroundColor Yellow "The above .rpt files were found in" $CrystalSettings.InputFolderPath
} elseif ($ShowFilesOK -eq "N") {exit}
Write-Host ""
[string]$ProcessingOK=(Read-Host "[Y] to proceed with .rpt file processing, [N] to quit:")
if ($ProcessingOK -ne "Y") {exit}
Write-Host ""
Write-Host "______________________________________"
Clear
# create a dir inside the output path to hold this run's output
Write-Host -ForegroundColor Green "Creating folder to hold this run's output..."
$RunDir = (New-Item -Path $MainSettings.OutputPath -Name "$(Get-Date -f yyyy-mm-dd__hh_mm_ss)" -ItemType Directory)
$RunDir.FullName
# use .NET ArrayList because immutable PS arrays are very slow
$Success = New-Object System.Collections.ArrayList
$Failure = New-Object System.Collections.ArrayList
#loop through the collection again, this time processing each file and dumping the output to the output dir
$CrystalFiles | ForEach-Object -ErrorAction SilentlyContinue -Process {
$RelativePathName = $_.FullName.TrimStart($CrystalSettings.InputFolderPath)
$XmlFileName = "$RunDir\$RelativePathName.xml"
# force-create the file to ensure the parent folder exists, otherwise RptToXML will crash trying to write the file
New-Item -Path $XmlFileName -Force
# then simply delete the empty file
Remove-Item -Path $XmlFileName
Write-Host -ForegroundColor Green "Processing file" $RelativePathName
CMD /c .\RptToXML\RptToXml.exe $_.FullName $RunDir\$($_.FullName.TrimStart($CrystalSettings.InputFolderPath)).xml
if ($LASTEXITCODE -eq 0) {
Write-Host "Success" $Success.Add($RelativePathName)} else {Write-Host "Failure" $Failure.Add($RelativePathName)}
}
$Success | Export-CSV "$RunDir\CrystalSuccess.txt"
$Failure | Export-CSV "$RunDir\CrystalFailure.txt"
我讨厌这样做,回答我的问题,但我已经找到了解决办法现在。
循环之前:
# Disable WER temporarily
Set-ItemProperty "HKCU:\Software\Microsoft\Windows\Windows Error Reporting" -Name DontShowUI -Value 1
循环后:
# Reset the WER UI reg key
Set-ItemProperty "HKCU:\Software\Microsoft\Windows\Windows Error Reporting" -Name DontShowUI -Value 0
这将通过从另一个脚本调用此脚本加以改进:
- 获取的当前值要修改的关键字
- 更改它们
- 调用,它返回控制,即使它崩溃
- 返回的雷吉·基斯的原始值
你总是可以运行的可执行文件作为后台作业,然后使用'等待,工作呼叫者脚本'带'-Timeout'参数,并且如果作业在合理的时间内没有完成,则取消该作业,该作业应该停止无响应的应用程序及其弹出窗口。 – TheMadTechnician