質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

Q&A

解決済

1回答

1486閲覧

Powershellで、永久ループの処理と、フォームの処理の合体方法

swsfb3bgh5hjh

総合スコア1

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

0グッド

0クリップ

投稿2023/01/09 00:44

前提

powershellで、永久ループで、処理するシステムを作っています。
一つの処理が終わると60秒スリープし、また処理を始めるという繰り返しです。
処理中に、if文による条件に一致したら、ログ記録のため、フォームにその時刻を追記する、ということをやりたいです。

フォーム表示スクリプトと、永久ループの処理スクリプトは、別々に作成済みです。

実現したいこと

フォーム表示スクリプトと、永久ループの処理スクリプトを、合体させたいです。

発生している問題

フォームに表示するスクリプトは、ShowDialog() の時点で、処理が止まってしまいます。
どのように合体させたらよいでしょうか?

該当のソースコード

・フォーム表示スクリプト(概略)

powershell

1$form = New-Object System.Windows.Forms.Form 2$Box = New-Object System.Windows.Forms.ListBox 3$form.Controls.Add($Box) 4$form.ShowDialog() #←ここで止まってしまう。

・永久ループの処理スクリプト(概略)

powershell

1whlle(1){ 2 # ~~ここに、時間がかかる、長い処理~~ 3 if ($flag -eq 1){ 4 $d = get-date 5 $Box.Items.Add($d) 6 } 7 Start-Sleep -s 60 #処理後、60秒間スリープ。 8}

試したこと

イベントを発生させればよいのかと思いますが、
Timer.intervalだと、等しい時間間隔のイベント発生になってしまいます。
処理が終わったら60秒後にイベントが発生するようにしたいです。

補足情報

powershell 5.1
Windows 10

以上、ご教示いただければ幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2023/01/09 02:39

ShowDialog は止まります。 Show なら止まりませんが、それが意図した動きかどうかこの質問からは判断できません。
guest

回答1

0

ベストアンサー

■永久ループとフォームの合体サンプル

PowerShell

1Add-Type -AssemblyName System.Windows.Forms 2$form = New-Object System.Windows.Forms.Form 3$form.Width = 640 4$form.Height = 480 5$Box = New-Object System.Windows.Forms.ListBox 6$Box.Width = 400 7$Box.Height = 400 8$form.controls.add($Box) 9$form.Select() 10$Global:exit_F = $False 11function SUB{ 12 While(1){ 13 # ~~ここに、時間がかかる、長い処理~~ 14 $flag = 1 15 if ($flag -eq 1){ 16 $d = get-date 17 $Box.Items.Add($d) 18 } 19 # 1秒間の停止を60回ループします 20 for ( $N=1 ; $N -le 60 ; $N=$N+1 ){ 21 [System.Windows.Forms.Application]::DoEvents() 22 if ( $Global:exit_F -eq $True ){return} 23 [console]::TreatControlCAsInput = $True 24 While ($host.UI.RawUI.KeyAvailable){ 25 $Key = $host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown,IncludeKeyUp,AllowCtrlC') 26 if ( $Key.KeyDown -eq $True ){ if (($Key.VirtualKeyCode -eq 67) -and ($Key.ControlKeyState -eq "LeftCtrlPressed")){return}} 27 } 28 Start-Sleep -m 1000 # 1秒間の停止 29 Write-host $N 秒間停止しています 30 $Box.Items.Add("$N 秒間停止しています") 31 } 32 } 33} 34$form.Add_Closing({ $Global:exit_F = $True }) 35$form.Add_KeyDown({ if ($_.KeyData -eq "C, Control"){ $Global:exit_F = $True } }) 36$form.Add_Shown({ SUB ; $form.Dispose() ; $form.Close() }) 37$form.ShowDialog() 38$form.Dispose() 39$form.Close() 40

■手順■
①拡張子ps1ファイルを作成して、このプログラムを貼り付けて保存します。
②ps1ファイルをコンテキストメニューから「PowerShell で実行」を選択します。

※フォームとコンソール両対応です( Ctrl+Cキーで終了 )

※お手数ですが分からない命令文はWeb検索をご利用ください。

投稿2023/01/15 02:09

ccc-

総合スコア342

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

swsfb3bgh5hjh

2023/01/15 03:16

このスクリプトを実行したところ、思い通りに動きました。リストボックスにしていただいて、ありがとうございます。やはり1秒ごとに判定が適切な解決手段のようですね。裏で動かすプログラムなので、1秒ごとのタイマーは高負荷すぎるのでは、と不安でしたが、10msまで縮めても最近のCPUだと充分、低負荷でした。GUI操作感の多少のモタつきは許容されるので、1秒ごとタイマーで実装したいと思います。大変助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問