【问题标题】:Folder Picker not loading outside ISE文件夹选择器未在 ISE 外部加载
【发布时间】:2017-05-12 15:05:32
【问题描述】:

我有一个以文件夹选择器对话框开头的脚本,但是我知道 POSH 不能像那样在 ISE 之外执行脚本(STA 与 MTA),所以我有一个单独的脚本来点源它。

如果用户按下取消,我会在第一个脚本中处理错误:

if ($Show -eq "OK") {
    return $objForm.SelectedPath
} else {
    Write-Error "Operation cancelled by user."
    exit
}

现在我需要第二个脚本(调用第一个脚本的那个)来检测相同的取消。

这是我目前所得到的:

"Choose a folder containing the items to be moved..."
""
try {
    powershell -STA -File "C:\Test\Script.ps1"
    ""
    "Operation completed. An event log has been created:"
    (Resolve-Path .\).Path +"\log.txt"
    ""
    "Press any key to continue..."
    ""
    $x = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
} catch {
    if ($LastExitCode -ne 0) { exit $LastExitCode }
    Write-Host "User cancelled the operation."
    ""
    "Press any key to continue..."
    ""
    $x = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}

这给了我一个令人讨厌的红色文本多行写入错误异常。

在 C:\Test\Script.ps1:27 char:30 + $folder = Select-FolderDialog

我不确定为什么它会生成引用另一个脚本的错误消息,因为另一个脚本运行良好(当然来自 ISE)。

所需的输出:

如果用户取消文件夹选择器,我只想显示一条干净整洁的错误消息:

用户取消了操作。
按任意键继续。

编辑

这是我拥有的文件夹选择器脚本。它在 ISE 中运行良好,但是当您右键单击并选择使用 Powershell 运行时,它只会启动一个空白提示窗口。为了防止最终用户意外编辑脚本,我希望它从 ISE 外部运行。顺便说一句,我正在使用 POSH 2。

 # Function for folder picker dialog
Function Select-FolderDialog
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null     

$objForm = New-Object System.Windows.Forms.FolderBrowserDialog
# Default location is script's location
$objForm.SelectedPath = (Resolve-Path .\).Path
$objForm.Description = "Select Folder"
$Show = $objForm.ShowDialog()
If ($Show -eq "OK")
{Return $objForm.SelectedPath}
    Else
    {
    Write-Error "Operation cancelled by user."
    Exit
    }
}
$folder = Select-FolderDialog #contains user's selected folder

【问题讨论】:

  • 所以你正在调用脚本一(镜头一),而这应该调用脚本二?分割成单独的文件有什么意义?
  • 我同意 restless1987,但不明白您为什么要将文件夹选择拆分为它自己的脚本。就我个人而言,我只有一个函数,我将它放入需要它来执行文件夹选择对话框的脚本中,但它也可以很容易地成为它自己的 .ps1 文件,我点源来加载该函数。我也很好奇你为什么要这样调用 PowerShell 并强制 STA 加载脚本。
  • 我现在找不到该页面,但我看到了一个关于我遇到的问题的论坛。一切都很好,直到我意识到原始脚本根本不会从资源管理器中运行,只能从 ISE 中运行。有人提到这是 STA 与 MTA 的问题(没有线索),然后建议创建第二个脚本来点源它。那行得通。除了我很快意识到它没有错误处理。我很想只有一个脚本。但是如何让它在 ISE 外部工作?
  • 我更新了我原来的帖子。请查看“编辑”的位置。

标签: powershell


【解决方案1】:

仅将您的函数保留在您的第二个脚本中,点源文件以加载该函数,然后将 $folder = Select-FolderDialog 调用放在您的主脚本中,例如:

"Choose a folder containing the items to be moved..."
""
try {
    . "C:\Test\Script.ps1" # this dot sources the function from the second file (no need to call a separate Powershell process to do this, as data from that process won't be returned to the primary process calling it)

    $folder = Select-FolderDialog # this runs the function in your original script, storing the result in the $folder variable

    ""
    "Operation completed. An event log has been created:"
    (Resolve-Path .\).Path +"\log.txt"
    ""
    "Press any key to continue..."
    ""
    $x = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
} catch {
    if ($LastExitCode -ne 0) { exit $LastExitCode }
    Write-Host "User cancelled the operation."
    ""
    "Press any key to continue..."
    ""
    $x = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}

【讨论】:

  • 看来这种调用脚本的方法不能正常工作(至少对于我的版本)。它只是启动一个带有打开消息的 powershell.exe 窗口,而不是文件夹选择器。我试了好几次了。
  • 看起来 try/catch 是失败点。我注意到 catch host 消息从未出现。即使该功能被取消,它也永远不会说“用户取消了操作”。所以我删除它只是为了看看会发生什么,我只是留下了点源和主机消息,它的操作与 try/catch 完全相同。
猜你喜欢
  • 2018-12-30
  • 2011-07-15
  • 1970-01-01
  • 2013-05-30
  • 2017-12-04
  • 1970-01-01
  • 1970-01-01
  • 2015-08-21
  • 1970-01-01
相关资源
最近更新 更多