2023年追記
「Utility - Environment」の「Read Memory Stats」でこれと同じようなことができるっぽいです。
出来合いのアクションがあったのか……。
これを書いた理由
たとえばブラウザが複数枚開いていたとして、どのブラウザをアタッチして処理に使うか、というのは
UiPathだったらブラウザ変数で管理すればいいのですよね。
しかしBlue Prismにはブラウザ変数がないので、どうしよう……と試行錯誤していたときに書いたものです。
ずいぶん前に書いて死蔵してたものなので、こちらに記録しておこうかなと……。
プロセスIDを取得するには
まずプロセスIDって何か(ごめんなさい私がレベル低いのでそこからです……)というのは
Process Explorer(Microsoftの)
っていうのがあって、これで詳しいプロセス名とかプロセスIDとか見ることができて便利です。
こんなやつ
これで見ると、同じアプリとかブラウザが複数起動していてもプロセスIDが異なるので、プロセスIDで一意に指定できることがわかります。
そのプロセスIDを取得するのは
特定のexeのPIDを取得する方法について(teratail)
プロセス名からプロセスを取得するのは
指定した名前のすべてのプロセスを取得する
コードステージでコレクションをどうにかするのは
How to store data into a collection form string in Blue Prism(stackoverflow)
これのなかに書いてあるGetTypeとかDataTypeっていうのは何かっていうと
DataColumn.DataType プロパティ
名前空間はデフォルトで設定されているSystem.Dataなので、今回は追加で設定するものはなさげ。
これらを踏まえて作ったもの
入力引数がProcessName(テキスト)
出力引数がProcesses(コレクション)
です。
- まず、コレクションに列を2列(プロセスID、ウィンドウの名前)作成して
- そのプロセス名のプロセスを全部取得し
- 取得したプロセスのIDと名前を順にコレクションに格納
という手順です。
Processes = new DataTable();
Processes.Columns.Add(new DataColumn("PID", typeof(int)));
Processes.Columns.Add(new DataColumn("WindowTitle", typeof(string)));
foreach (var p in System.Diagnostics.Process.GetProcessesByName(ProcessName))
{
try
{
Processes.Rows.Add(new object[] {p.Id, p.MainWindowTitle});
}
catch (Exception) { }
}
添削していただきました!
たかぎさんありがとうございます!大好き!
前半(出力用コレクションの準備)
添削前
DataColumn col1 = new DataColumn();
col1.DataType = System.Type.GetType("System.Int32");
col1.ColumnName = "PID";
Processes.Columns.Add(col1);
DataColumn col2 = new DataColumn();
col2.DataType = System.Type.GetType("System.String");
col2.ColumnName = "WindowTitle";
Processes.Columns.Add(col2);
添削後
Processes.Columns.Add(new DataColumn("PID", typeof(int)));
Processes.Columns.Add(new DataColumn("WindowTitle", typeof(string)));
添削内容
列追加が1行ずつになった!
添削前のコードのお手本になったのは、これです。
DataTable クラス
// Create a new DataTable.
System.Data.DataTable table = new DataTable("ParentTable");
// Declare variables for DataColumn and DataRow objects.
DataColumn column;
DataRow row;
// Create new DataColumn, set DataType,
// ColumnName and add to DataTable.
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "id";
column.ReadOnly = true;
column.Unique = true;
// Add the Column to the DataColumnCollection.
table.Columns.Add(column);
この添削後に出てくるtypeofっていうのは
C#で型を判別するtypeofとis演算子
typeofはJavaScriptにもあるから知ってる!書き方違うけど!
typeof(MDN)
後半(プロセスを取得して出力用コレクションに格納)
添削前
//そのプロセス名のプロセスを全部取得し
System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcessesByName(ProcessName);
//取得したプロセスのIDと名前を順にコレクションに格納
foreach (System.Diagnostics.Process p in ps)
{
DataRow row = Processes.NewRow();
Processes.Rows.Add(p.Id,p.MainWindowTitle);
}
添削後
foreach (var p in System.Diagnostics.Process.GetProcessesByName(ProcessName))
{
try
{
Processes.Rows.Add(new object[] {p.Id, p.MainWindowTitle});
}
catch (Exception) { }
}
添削内容
行追加して、追加した行に値を設定して、って2行でやってたところが1行になりました。
あと、まずプロセスを取得して、それから取得したプロセスに対してforeachをまわす、と書いていたところが
1個にまとめられました。
それからエラーハンドリングも足されましたね。
ぶっちゃけ、落ちたらどのみちオブジェクトから例外スローされて返るからいっかと手を抜いてました(テヘ
終わりです(あんまり終わりではない)
コレクションに予め列を作っておけばコードステージで列を追加することないんじゃないかと思って試したのですが、そこはまだうまくいかず……
やりかたを教えてください。