🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

2395閲覧

[C#]他プロセスのプログラムに配置されたElementHostが含むコントロールを取得したい。

退会済みユーザー

退会済みユーザー

総合スコア0

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2019/11/01 08:12

編集2019/11/13 07:53

解決方法

他のプロセスに対して働きかける方法ではありません。
実行ファイルを自作のプログラムから参照しています。そのためElementHostインスタンスへの参照を他プロセスから取得する部分はありません。

ElementHost.Childプロパティを利用することで実現できました。
私の場合は以下のような流れで取得できました。

c#

1// この行まででObject controlとしてElementHostのインスタンスが存在するとします。 2 var eh = (System.Windows.Forms.Integration.ElementHost)control; 3 var cc = (System.Windows.Controls.ContentControl)eh.Child; 4 var pa = (System.Windows.Controls.Panel)cc.Content; // Gridである場合もあるかもしれませんね。 5 System.Windows.Controls.UIElementCollection children = pa.Children; 6 // なお、確実にChildrenの第1要素がButtonである場合は以下のように取得できています。 7 var button = (System.Windows.Controls.Button)children[0];

まんまこのページで見た書き方を利用しています。

前提・実現したいこと

他プロセスのプログラムに配置されたElementHostに含まれるコントロールを取得したい。

いま、自分が開発したC#プログラムから他社が開発したC#プログラムを自動的に操作しようとしています。
TextプロパティやNameプロパティで得られる情報(以下情報と呼びます)を読み込めていますが、ElementHostなるコントロールに含まれるコントロールについては一切手出しが出せない状態です。

宜しくお願いいたします。

該当のソースコード

なお事情により余り詳しくコードを載せるわけにはいかないので雰囲気をつかんでいただける程度の内容に限られます。

c#

1for each(var f in Application.OpenForms) 2{ 3 if( f.Name != "uitarget") // 仮にuitargetというNameのフォームになっている事にします 4 { 5 continue; 6 } 7 8 for each( var c in f.Controls) 9 { 10 for each( var c_child in c.Controls) // このようにループをまわしてもElementHost.Controlsの要素数は0のようです 11 { 12 // テキストファイルとかに情報を書き出す処理 13 } 14 } 15}

発生している問題・エラーメッセージ

性質について余り理解できていないので確証は無いのですが、おそらくElementHost内にあるコントロールのみ走査が達していないのだと思います。
今、情報が得られないTextBoxButtonと思われるコントロールはそれらが確実にフォームデザイナーで配置するようなコントロールである確証がない事はご協力いただく皆様には白状しておこうと思います。

というのも自動的に操作しようとするソフトはお客様のマシンにインストールされていて、なおかつSpy++に類するソフトを利用しようにも外部ソフトのインストールは上司より忌避するよう指示されているためです。また開発マシンに入れて動作させるのは仕様上不可能です。

試したこと

例えばTableLayoutコントロールに含まれるコントロールはControlsプロパティで得られるのでElementHostにおいても同様だと思ったのですがうまくいかず、他の方法を探したもののElementHostについてイマイチ理解が及ばず作業が進まずにいます。

ElementHost.Childプロパティにも興味が惹かれたのですがこれによって得られるUIElementを役立てる方法が分からず現在使用していません。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

  • Visual Studio 2015 SP1
  • Windows 7 64bit(開発環境)
  • Windows 10(実行環境)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ウィンドウではないので、実行中の状態を取得するのは無理です。

そのプログラムを参照した場合は、Child プロパティが使えます。
ElementHost.Child プロパティ (System.Windows.Forms.Integration) | Microsoft Docs

投稿2019/11/01 08:27

Zuishin

総合スコア28669

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/11/05 00:23

回答ありがとうございます。 ウィンドウでは無いのですね・・・厄介な。 ここでお聞きしたいのですが >そのプログラムを参照した場合は というのは、対象のプログラムの実行ファイルを VisualStudio>ソリューション エクスプローラ>参照マネージャ>参照 に含める操作を指すのでしょうか? またChildプロパティを利用できても、UIElementが私の目的である「表示される文字列の取得」や「クリック時イベントの呼び出し」を行えるようなモノなのか判断がつかないのでなんともはや・・・
Zuishin

2019/11/05 00:36

その参照です。参照されたアセンブリは参照したプロセスで動かすことができるので、その上で表示される文字列の取得やクリック時のイベントの呼び出しは行えます。
Zuishin

2019/11/05 00:40

参照したプロセスではなく動作中のプロセスを操作したい場合は、DLL インジェクションを調べてください。
退会済みユーザー

退会済みユーザー

2019/11/05 07:16 編集

よく見返してみたらこのプログラムは対象プログラムをAssembly.LoadFrom()関数で呼び出しているので「参照」はしていました。(先に上げた静的参照ではなく動的参照ですね。) そこで、 >参照されたアセンブリは参照したプロセスで動かすことができるので、その上で表示される文字列の取得やクリック時のイベントの呼び出しは行えます。 とアドバイスをいただけましたが これはControlsプロパティで辿れないが何らかの方法で呼び出せるのか Controlsプロパティでの探索に不備があるためたどり着かないだけなのか どちらかである可能性が高いと思いますのでその方向で攻めようと思います。 (DLLインジェクションは調べてみた結果C++でDLLを作ったり戻り値が欲しかったらどうやって受け渡すかとか悩みが尽きないのでなるべく避けたい内容でした・・・)
Zuishin

2019/11/05 07:57

ElementHost は何かの Controls に入っているはずです。何かは Form かもしれないし Panel かもしれません。
退会済みユーザー

退会済みユーザー

2019/11/05 08:17

ありがとうございます。 何度もお尋ねして申し訳ありません。 >ElementHost は何かの Controls に入っているはずです。 質問の書き方が悪く誤解させてしまったかもしれません。 いま、ElementHostはPanelに含まれているであろうということは分かっています。 ElementHostにButtonやTextBoxのようなものが含まれており、それをクリックしたりテキストを読み取ったりする必要がある状況です。 今更ながらElementHost.FindForm()関数があることに気づいたので明日にも何かしら得られないか試してみるつもりです。
Zuishin

2019/11/05 08:58

FindForms は ElementHost が取得できているとき、そのフォームを取得するメソッドです。逆のものが必要なのではないでしょうか。
退会済みユーザー

退会済みユーザー

2019/11/13 03:07

その通りでした。ありがとうございます。 別スレッドで対象のプログラムを起動させていたのでInvokeするために利用できました。怪我の功名というか・・・w
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問