LoginSignup
1
0

More than 3 years have passed since last update.

UiPathのPicture in Pictureセッションを自動終了させる

Posted at

この記事の要約

  • UiPathのプロセス終了時に、PiPセッションを自動終了する方法の説明
  • アイデア
    • Invoke PowerShellアクティビティでshutdown.exe /lを実行 -> PiPセッションからサインアウト
    • カレントセッションがPiPセッションか否かをquser.exeで判定

Picture in Picture機能とは

Picture in Picture(以降PiP)は、UiPath v2020.4で追加されたAttended Robot用の機能で、
Robotを別ウィンドウ上の別セッション(PiPセッション)上で実行させることができる便利な機能です。

ピクチャ イン ピクチャ
https://docs.uipath.com/robot/lang-ja/docs/picture-in-picture

PiPセッションはユーザーの画面・セッションとは独立しているため、以下のようにRobotを安定して実行させることができるようになります。

  • ユーザーのマウス・キーボード操作によるRobotの妨害・誤動作を防げる
    • Robot実行中でも他の作業をできる
  • ユーザーがスクリーンロックしてもRobotが実行を継続できる
    • マウスクリックなどの一部のアクティビティは、スクリーンロック中は動かない

ただし、PiPにもいくつかの制限事項があり、ちょっと厄介なのが下記2点。

  • PiP セッションを事前に閉じる必要があるため、PiP セッションが開いている間はマシンを再起動またはシャットダウンできません。
  • 一度に開始できるピクチャ イン ピクチャ セッションは 1 つのみです。

Attended Robotを共有PCで運用している場合、あるユーザーが実行してPiPセッションを開いたまま放置していると、他のユーザーが使うことができなくなってしまいます。また、PCの再起動・シャットダウンもできなくなると、Windows Updateも滞ってしまい、共有PCの運用に支障が出てしまいます。

PiPセッションを自動終了させる方法

UiPathのプロセス終了時にPiPセッションも自動終了してくれると嬉しいのですが、残念なことに v2020.10 時点ではそのような機能はありません。
なので、作ってしまいましょう

基本的なアイデア

PiPセッションは、PiPセッションからサインアウトすることで終了させることができます(PiPウィンドウも自動で閉じます)。
サインアウトはスタートボタンからだけでなく、shutdown.exe /lをコマンドライン実行することでも行えるので、基本的なアイデアはInvoke PowerShellアクティビティでshutdown.exe /lを実行することになります。
ただし、UiPathのプロセス内でサインアウト処理を行ってしまうと、Robotが外部から強制終了されて異常終了の扱いになってしまうため、shutdown.exeをRobotとは別プロセスで実行するようにします。やり方は下記の通り。

別プロセスでshutdown.exeを実行
Start-Process -FilePath shutdown.exe -ArgumentList '/l'

Robot終了直前にいきなりサインアウトが走るのは少し怖いので、例えば5秒待ってからサインアウトするときは下記のようにStart-Sleep 5を挟みます。

5秒待ってからサインアウト
Start-Process -FilePath powershell.exe -WindowStyle Hidden -ArgumentList '-Command Start-Sleep 5; shutdown.exe /l'

ワークフローやシーケンスの最後で上記PowerShellスクリプトをInvoke PowerShellアクティビティで実行するだけで、「PiPセッションを自動終了させる」という当初の目的は概ね達成できます。
しかし、開発・テストの都合でPiP機能を使わずにプロセスを実行した場合にもサインアウトが走ってしまうという問題があります。

カレントセッションがPiPセッションか否かを判定する

PiPセッションの場合だけshutdown.exe /lを実行させるようにするために、カレントセッションがPiPセッションか否かを判別する方法を考えます。
幸い、環境変数%SESSIONNAME%の値によって、カレントセッションがPiPセッションか否かをある程度判断できます。
%SESSIONNAME%を取得するにはquser.exeを使います1

quser.exe
PS C:\> quser.exe
 USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
 takeruko              console             1  Active          .  3/4/2021 09:31
 takeruko              rdp-tcp#16          8  Active          .  3/4/2021 09:47
>takeruko              7a78855482a0...    14  Active          .  3/4/2021 12:56

quser.exeを実行すると、PC上の全てのセッションが一覧表示されます。
行の先頭に>が付いているID:14がカレントセッションです。
SESSIONNAMEの値はセッションの接続方法によって以下のような値を取るようです。

SESSIONNAMEの値 セッションの種類/接続方法
console ローカルからサインイン
rdp-tcp#... リモートデスクトップ接続
上記以外 PiPセッションなど

今回はカレントセッションがユーザーセッション(ローカルからのサインインやリモートデスクトップ接続)ではない事が判別できればいいので、以下のようなPowershellスクリプトを実行します。

カレントセッションがPiPセッションの場合にだけshutdown.exeを実行する
# quser.exeは%windir%¥Sysnative 配下
$quser = $env:windir + '\Sysnative\quser.exe'
$csv = . $quser |  ForEach-Object -Process { $_ -replace '\s{2,}',',' } | ConvertFrom-Csv
foreach ($row in $csv) {
  if ( $row.USERNAME.StartsWith('>') -and $row.SESSIONNAME -notmatch '(console|rdp-tcp#.+)' ) {
    Start-Process -FilePath powershell.exe -WindowStyle Hidden -ArgumentList '-Command Start-Sleep 5; shutdown.exe /l'
  }
}

後は、上記スクリプトをInvoke PowerShellアクティビティのコマンドテキストに貼り付けて、TypeArgumentStringスクリプト入力にチェックを入れればOKです。
7c11aeb3-792a-468d-8d21-8ad844a5c9f0.jpg
fa917211-1083-4520-9581-2ba8f0dc1929.jpg
44a7f745-fef8-46d5-9f93-35f45ea90527.jpg

以上


  1. Get Environment Variableアクティビティとかで%SESSIONNAME%を直接取得できると楽なんですが、UiPathのRobotは仕組み上一部の環境変数を取得できない模様。 

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0