読者です 読者をやめる 読者になる 読者になる

ささいなことですが。

Windowsアプリテスト自動化ライブラリFriendly開発者の日記です。

Friendly なんで別プロセス操作できるの?

Friendly(Win32, WinForms, WPF)

これは「Friendly Advent Calendar 2014 - Qiita」の記事です。

Frienldyが対象プロセスを操作するときのスレッドの処理に関して説明しました。

今日は、そもそも何で別プロセス操作できるの?って話をします。
内部的なこともちょっと知っておくと、理解が深まるかなーと。
でも、この辺は知らなくても使えますので、分からないところあっても気にしないでください。

Windowsは各プロセスごとにメモリ空間を割り当ててお互いに干渉できないようにしています。
プロセス間通信はありますが、操作されるアプリがCOMインターフェイスWCFなどで明示的にインターフェイスを公開しない限りはできませんよね。
Friendlyはそんなものお構いなしに内部のAPIを呼び出せています。
なぜでしょうか?
本当に魔法ですか?

答え:言うこと聞いてくれるモジュールをインジェクションする

まあ、答えを聞くと、なーんだって感じですね。
イメージです。
f:id:ishikawa-tatsuya:20141206001014p:plain

その結果これですw
これはMVP Global SummitのShowcaseで2位とった時に使ったサンプルです。
MVP Showcase Winners! - The Microsoft MVP Award Program Blog - Site Home - MSDN Blogs

海外の方にから「Crazy!」「Amazing!」と大好評でした。

技術的には、
①ネイティブのDLLをインジェクション
②.Netのモジュールを実行させる
③そのモジュールで操作側のプロセスから指令を受けてリフレクション実行
っていう手順です。
まあ、詳細はまた別途書こうかなーって思っています。
コードはこちらにありますよ。
Codeer-Software · GitHub

あ、一部はわんくま横浜勉強会でも話してきました。

CLRとAppDomainは?

そうそう、対象プロセス内で処理を実行するスレッドに関しては書きましたね。
でも、CLRとAppDomainはどこやねん!って気になりますよね?(そうか?

CLR

CLRのバージョンは合ってないと操作できません。
これも、WindowsAppFriendのコンストラクタで指定するのですね。
でも大抵は指定なしでOKです。
その場合は、以下のルールになります。
CLRが一つの場合は、そこで動作する
複数あった場合は例外
CLRを使っていない場合(ネイティブアプリ)の場合は操作プロセスのCLRと同じバージョンを使う

もちろん、指定がある場合はそれを使います。
でも、これが必要なのはサイドバイサイドで複数CLRを利用しているアプリを操作する場合のみです。

AppDomain

これはデフォルトのAppDomainを使います。
現在複数AppDomainを使っている場合は、デフォルト以外のAppDomainに含まれる操作は使用できません。
(そんなアプリってあんまりないですよね。)

でも、これはちょっと悔しいので近いうちに対応しようと思っています。
こんな感じのインターフェイスにするかなー。

WindowsAppFriend[] all = WindowsAppFriend.AttachAllAppDomain(process);

明日に続く・・・