LoginSignup
2
4

More than 1 year has passed since last update.

[BluePrism]プロセス名からプロセスIDとウィンドウ名を取得するオブジェクトを書きました。 #blueprism

Last updated at Posted at 2019-12-17

2023年追記

「Utility - Environment」の「Read Memory Stats」でこれと同じようなことができるっぽいです。
出来合いのアクションがあったのか……。

これを書いた理由

たとえばブラウザが複数枚開いていたとして、どのブラウザをアタッチして処理に使うか、というのは
UiPathだったらブラウザ変数で管理すればいいのですよね。
しかしBlue Prismにはブラウザ変数がないので、どうしよう……と試行錯誤していたときに書いたものです。
ずいぶん前に書いて死蔵してたものなので、こちらに記録しておこうかなと……。

プロセスIDを取得するには

まずプロセスIDって何か(ごめんなさい私がレベル低いのでそこからです……)というのは
Process Explorer(Microsoftの)
っていうのがあって、これで詳しいプロセス名とかプロセスIDとか見ることができて便利です。
こんなやつ
processexplorer.jpg
これで見ると、同じアプリとかブラウザが複数起動していてもプロセス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個にまとめられました。

それからエラーハンドリングも足されましたね。
ぶっちゃけ、落ちたらどのみちオブジェクトから例外スローされて返るからいっかと手を抜いてました(テヘ

終わりです(あんまり終わりではない)

コレクションに予め列を作っておけばコードステージで列を追加することないんじゃないかと思って試したのですが、そこはまだうまくいかず……
やりかたを教えてください。

2
4
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
2
4