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

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

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

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

Q&A

解決済

1回答

4943閲覧

Start-Processコマンドレットにて外部プロセスを実行後、Start-Jobコマンドレットにてジョブの完了ステータスを確認しタイムアウト判定を行いたい。

beginner_Jiro

総合スコア10

PowerShell

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

0グッド

0クリップ

投稿2020/04/10 04:35

いつもお世話になっております。
Power Shellにてタイムアウトの判定を設けたいと考えています。

目的

別のpowershellプログラムを呼び出すPowershellのプログラムを開発しております。
呼び出し元Aのプログラムから呼び出し先Bのプログラムを実行し呼び出し先Bの完了時間に
よってタイムアウトの判定を設けたいと考えております。

コード

$_mypass = Split-Path $MyInvocation.MyCommand.Path #powershell.exeが存在しているパスを格納 $Powershell = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" #起動したいジョブに渡す引数を格納 $_Automd = 1 #起動したいジョブの格納先と引数を格納 $ScriptFile = "$_mypass\log_scaveng.ps1 $_Automd" #powershell.exeが実行するコマンドを格納 $Argument = "-Command $ScriptFile" #タイムアウトの秒数を指定 $_TimeoutSecond = 600 #以下コメントアウトは単体で実行されることを確認 Start-Process -FilePath $Powershell -ArgumentList $Argument #Start-jobコマンドとStarr-Processコマンドを併用 実行されず $_Mainjob = Start-Job {Start-Process -FilePath $Powershell -ArgumentList $Argument} コード

疑問点及び考察

Start-Jobコマンドレットにてパラメータに対し処理を渡す際、パラメータに指定するコマンドに
Start-Processは使えないのでしょうか。また、アンパサンドを使用した外部プログラムの実行方法と
Start-Jobコマンドレットの併用も行えませんでした。
外部プログラムの実行のジョブ状態をStart-Jobコマンドレットにて取得するのは不可能なのでしょうか。
どなたか、ご回答いただければ幸いです。

以上になります。よろしくお願いいたします。

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

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

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

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

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

Zuishin

2020/04/10 04:41

Job ではないのでできないと思います。System.Diagnostics.Process を返すので、それをもとにプロセスの状態を取得し、必要であれば kill してください。
beginner_Jiro

2020/04/10 05:17

Zuishin様 いつもお世話になっております。ご回答ありがとうございます。 System.Diagnostics.Processを返すというのはStart-Processコマンドレットの戻り値として 帰ってくるものという認識で間違いないでしょうか。 またStart-ProcessコマンドレットがSystem.Diagnostics.Processを返すには-PassThruオプションを 使用しないと返ってこないようなので追加で-PassThruオプションを付与しようと思います。 プロセスの状態を取得するのはいずれかのメソッドを使用する解釈ですよね? 質問ばかりで申し訳ありません。 ただ、かなりやりたいことには近づけているような気がします。 ご教授いただきありがとうございます。
Zuishin

2020/04/10 05:23 編集

どちらもその通りです。 次に C# でのサンプルがありますが、HasExited プロパティと Kill メソッドを使ってください。CloseMainWindow() は GUI アプリの時に有効ですが、コンソールアプリでは使えません。ただし Kill は問答無用でプロセスを終了させるので、そのプロセスの残りの処理ができなくなります。 https://docs.microsoft.com/ja-jp/dotnet/api/system.diagnostics.process.hasexited?view=netframework-4.8
beginner_Jiro

2020/04/10 05:40

Zuishin様 上記リンクにてドキュメントのご提供ありがとうございました。 プロセスの状態について取得することが可能になりました。 タイムアウトの判定について引っかかってしまった場合の後処理はKillにて 対応しようと思います。(以降の処理については切り捨てる方向で問題ないので) 本当にありがとうございました。 こちらもベストアンサーに選ばせていただきたいのですが、 回答として、ご記入し直していただくことは可能でしょうか? 以前のように自己解決としてのご希望がありましたらそのようにさせていただきます。 本当にありがとうございました。また機会がございましたら、よろしくお願いいたします。
guest

回答1

0

ベストアンサー

PowerShell のバックグラウンドジョブはプロセスとは別物です。Start-Job { notepad } を実行するとメモ帳が起動しますが、メモ帳を開いたまま Get-Job で見ると、ジョブは終了しています。メモ帳を起動するという仕事が終わったからです。

メモ帳が終了するまで Job を待機させておくこともできますが、それも迂遠なので、この場合は直接プロセスを実行するのが良いと思います。

Start-Process はデフォルトでは Process オブジェクトを返さないようですが、-PassThru オプションを指定することによって返します(beginner_Jiro さんによって確認)。
Process クラス (System.Diagnostics) | Microsoft Docs

Process クラスは紐づけられたプロセスに関する様々な情報を有し、またプロセスを扱うための有用なメソッドを持っています。この中で Process.HasExited プロパティ (System.Diagnostics) | Microsoft Docs が $true の場合、プロセスは終了しており、$false の場合実行中です。

Process.WaitForExit メソッド (System.Diagnostics) | Microsoft Docs を使うと、プロセスが終了するまで、または指定した時間が経過するまで待機することができます。また Process.Exited イベント (System.Diagnostics) | Microsoft Docs にイベントハンドラを登録すると、そのハンドラはプロセス終了時に呼び出されます。

プロセスは Process.CloseMainWindow メソッド (System.Diagnostics) | Microsoft Docs または Process.Kill メソッド (System.Diagnostics) | Microsoft Docs で終了させることができます。

CloseMainWindow メソッドは、そのプロセスのメインウィンドウを閉じるメソッドで、多くの場合、メインウィンドウが閉じたプロセスは、後処理をしてから終了します。ウィンドウがある際には最も安全な終了の仕方と言えます。

ウィンドウが無い場合には Kill メソッドを使いますが、これはそのプロセスを問答無用で中断させます。たとえばそのプロセスがファイルに書き込みを行っていた場合、バッファに溜まっていたデータが書き込まれる前に終了し、書き込み中のファイルが壊れることがあります。そこに留意して使ってください。

投稿2020/04/10 06:13

編集2020/04/10 06:46
Zuishin

総合スコア28662

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

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

beginner_Jiro

2020/04/10 06:31

Zuishin様 ご回答いただきありがとうございます。 私の追記いたしました質問も含め詳細な説明本当に助かりました。 ご回答いただきました内容に基づき、Start-Jobを噛ませずに、Start-Processから Process.HasExited プロパティを使用してジョブの状態を取得することでタイムアウトの判定の実装を実現することができました。 解決に直結するアドバイスと共にそれに付随した各情報についての記載・説明 を加味しベストアンサーとさせていただきます。 また一つスキルアップできました。本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問