ISE和PowerShell控制台中msgbox功能的结果不一致

时间:2015-12-28 15:27:52

标签: function powershell powershell-ise msgbox system.timers.timer

我正在摆弄计时器对象和消息框并碰到了一堵砖墙。

我正在尝试管理计时器对象并通过可重用的函数弹出。

我首先在自己和小部件上测试了大部分这些功能。由于一切正常,我决定将所有内容组合在一起。

在一起,它似乎不起作用,所以我将功能分解为基础:

$Thirtyaction

我仍然无法运行脚本,因为它在Elapsed操作(action)期间保持“挂起”状态。它在PowerShell控制台中显示的最后一件事是:action2else。所以我认为问题在于box函数,但是:

  • 如果我使用ISE调用脚本,它将按预期运行
  • 如果我先执行functionfile然后再执行该文件,它将再次停止/挂起(first / YesNo)msgBox
  • 如果我手动将msgBox函数输入控制台然后启动文件,它将显示msgBoxes,但不会正确执行Main script 6 1176 myfunc 6 1176 Elapsedaction ($Thirtyaction) 11 4236 语句中的代码(在(第二个/ OKonly)msgBox之后停止已经显示)

我无法想到任何有意义的方法,而且我花了很多时间尝试调试/切换/愚蠢等等。

edit1:新的一天和更多的信息。

我将功能更改为windows.Forms但没有运气。 然后我开始打印出脚本的所有函数和部分的线程ID,并且瞧瞧:

$action

Timedvent触发时触发的$Thirtyaction在新的PowerShell Runspace中运行,因此无法再访问之前定义的变量和函数。

我不知道如何解决这个问题或解决它,但至少我知道问题是什么。欢迎任何想法,感谢已经回答的人,并给了我一个正确方向的暗示!

使用解决方案和解决方法编辑

感谢另一位用户如果找到了如何从$Thirtyaction scriptblock中控制计时器属性的问题的答案:

link

我可以通过简单地在scriptblock

中对函数文件进行点处理来使用MsgBox函数

我对变量的解决方法是使用三个environement变量。我很确定这既不聪明也不是最佳实践,但在我的特殊情况下不应该是一个问题而且它有效。

这里的示例是我当前的 $ThirtyAction={ . .\testfunction.ps1 $Sender.stop() Write-Host "action" Write-Host "action2" if ((($ans=(Show-new-MsgBox -Prompt "Prompt" -Title "Title" -Icon "Warning" -BoxType "YesNo")) -eq "No") -or !($Env:Sessionsleepstate -eq 0)) { Write-Host $Env:Sessionsleepstate $Env:Sessionsleepstate = 3 if ($Env:Sessionsleepstate -eq 1) { Show-new-MsgBox -Prompt "Prompt" -Title "Title" } Show-new-MsgBox -Prompt "Prompt" -Title "Title" Write-Host "killfunction placeholder" } else{ $Sender.stop() Show-new-MsgBox -Prompt "Prompt" -Title "Title" $Sender.interval=300000 $Env:Sessionsleepstate = 1 $Sender.start() Write-Host "timer start" } } scriptblock:

UIPageViewController

1 个答案:

答案 0 :(得分:0)

多么有趣......我跑了一些支票。

首先,我认为只能从控制台窗口阻止GUI访问。但我发现如果你直接调用它(而不是来自计时器功能),消息框就会显示得很好:

Add-Type -AssemblyName "Microsoft.VisualBasic"
[Microsoft.VisualBasic.Interaction]::MsgBox("MyPrompt",[microsoft.visualbasic.msgboxstyle]::OKOnly,"title")

然后我认为这可能是一个线程,在控制台中,计时器会在不同的线程上调用该函数,而VisualBasic程序集会忽略或拒绝它。但我找到了

Write-Host ([System.Threading.Thread]::CurrentThread).ManagedThreadId
Write-Host ([System.AppDomain]::GetCurrentThreadId())

在主代码或定时器调用的函数中给出相同的值。

然后我认为可能无法再通过计时器功能访问该程序集。但我发现打电话

([Microsoft.VisualBasic.Interaction]::Beep())

从控制台窗口工作得很好。

所以这很奇怪。但是,似乎有一个简单的解决方法:如果您使用System.Windows.Forms.MessageBox,它确实按预期工作:

Add-Type -AssemblyName System.Windows.Forms
$Result = [System.Windows.Forms.MessageBox]::Show('Now I''ll be a son of a gun...', 'How about that?', 'YesNo', 'Warning')