ウィンドウを閉じる処理について

お世話になります。

ウィンドウを閉じるアクティビティとして「ウィンドウを閉じる(CloseWindow)」がありますが、こちらはどのウィンドウ閉じるか指定して使用するものと思います。

そうではなくて、デスクトップ上で開かれているウィンドウをとにかくすべて閉じる、といったことはUiPathで実現可能なものでしょうか。

用途としては、TryCatchを利用したエラー時の処理として、開いているウィンドウをすべて閉じるといったことができないか考えております。
本当に何も確認せずにすべて閉じていいのか検討は必要かと思いますが、まずはそのようなこと(特にウィンドウ名は指定せず、開いているウィンドウをすべて閉じる)といったことができるのかご教示いただければと思います。

「プロセスを取得」アクティビティで全プロセスを取得し、ProcessNameを判断して、閉じるではなく、「プロセスを強制終了」(Kill)アクティビティを発行するROBOTは作った事があります。

「プロセスを取得」アクティビティの戻り値がCollenction<Process>なので、それぞれのProcessのプロパティから情報を得られるかもしれませんね。

あまり答えになっていませんが、ご参考までに。。。

「ロボットが開いたウィンドウすべて」であれば、都度ウィンドウの要素を(List型などを利用して)格納しておき、例外処理時にFor Eachでウィンドウを閉じる処理を実装することで実現できると思います。
逆にロボットが関知しないウィンドウを閉じるのであれば、 @HANACCHI さんが書かれているような手段になるかと思いますが、プロセスを強制終了する処理は一般的に好ましくないことと、ProcessName をもとに判断させる必要が生じますので、やや手間になるかと思います。

1 Like

こんにちは

例えば以下のような感じになると思います。

  1. System.Diagnostics.Process.GetProcesses()でプロセスの一覧を取得します。
  2. プロセス一覧をfor eachで回します。
  3. 各プロセスのMainWindowHandleとProcessNameを取得します
  4. 画面をもたないプロセスのMainWindowHandleはIntPtr.Zeroになりますので、IF文で画面を持つものの処理を行います。あわせてUiPath製品まで落ちることを防いだり、ExplorerはOS上特殊な存在なのでこれらをクローズの対象としないようにします。
  5. Close Windowアクティビティで閉じます。WindowプロパティにNew UiPath.Core.Window(wndHandle)としてインスタンスを与えます。

一度お試しいただければと思います。

3 Likes

HANACCHI様

ありがとうございます。
ウィンドウを閉じるではなく、プロセスを終了ですか。
たしかに、動いているはずのプロセスくらいはわかると思うので、もしかしたらプロセスを終了させるのがよいかもしれませんね。
参考にさせていただきます。

よろしければ、解決の糸口になった書き込みに対して、「解決策」にチェックをお願いしますね。

cheez_RPA様

ありがとうございます。
ウィンドウを都度取得しておいて、それを使用するのですね。
確かに、プロセス終了は不要なプロセスを終了させないように気を付けないといけませんね。

そのあたり踏まえてどう実現するか検討してみます

Yoichi様

ありがとうございます。

なるほど、プロセスの一覧を取得しつつ、画面をもたないもの、その他終了させるべきではないものを除外して閉じるということですね。
まだ初心者ですが、一度試してみます。

Yoichi様

具体的に画像を載せていただいていたので、ご教示いただいている方法を試してみようと考えているのですが、なにぶんまだ作成に不慣れなもので、以下の点をさらに教えていただけますでしょうか。

1.「System.Diagnostics.Process.GetProcesses()でプロセスの一覧を取得」とのことですが、標準のアクティビティの「プロセスを取得」を使う事とはまた別なのでしょうか。
System.Diagnostics.Process.GetProcesses()だと左辺値の変数の型を何をしてよいのかわからず。。。

もし「プロセスを取得」のアクティビティを使用したとすると、以降の記述(for eachの部分)は変わりますでしょうか。

2.上記の「プロセスを取得」のアクティビティでプロセス一覧を取得したとして、各プロセスのMainWindowHandleの取得の部分ですが、右辺値の記述は「item.MainWindowHandle」であってますでしょうか。
左辺値をstring型の変数にして、右辺値を「item.MainWindowHandle.ToString」と記述してみたりしていますが、エラー(Option Script Onでは、遅延バインディングを使できません)がでてい路頭にまといかけてます。

質問の仕方がうまくないかもしれませんので、解決にあたり不足情報あればご指摘ください。

こんにちは

1.「System.Diagnostics.Process.GetProcesses()でプロセスの一覧を取得」とのことですが、標準のアクティビティの「プロセスを取得」を使う事とはまた別なのでしょうか。

「プロセスを取得」でもOKです。この場合CTRL+Kなどで自動的に変数を生成すると型も自動的に設定されます。

System.Diagnostics.Process.GetProcesses()だと左辺値の変数の型を何をしてよいのかわからず。。。

この場合はSystem.Diagnostics.Processの配列になります。ArrayOFから先のProcessを指定ください。

もし「プロセスを取得」のアクティビティを使用したとすると、以降の記述(for eachの部分)は変わりますでしょうか。

変わりません。
なおfor eachでのitemの型はSystem.Diagnostics.Processを指定してください。
そうすることにより、itemでのプロパティやメソッドが入力時補完されますし、余計な変換が不要になります。

2.上記の「プロセスを取得」のアクティビティでプロセス一覧を取得したとして、各プロセスのMainWindowHandleの取得の部分ですが、右辺値の記述は「item.MainWindowHandle」であってますでしょうか。
左辺値をstring型の変数にして、右辺値を「item.MainWindowHandle.ToString」と記述してみたりし>ていますが、エラー(Option Script Onでは、遅延バインディングを使できません)がでてい路頭にまといかけてます。

右辺はそれでOKです。左辺はIntPtr型(System.IntPtr型)の変数を作成してください。

まずは上記でお試しいただければと思います。