よろしくお願いいたします。
解決コード
まだ途中だけど
c#
1using System.Threading; 2using System.Reflection; 3 4public partial class Form1 : Form 5{ 6 ThreadUITarget m_uiAutomationTargetThread; 7 DataGridView m_uiAutoTargetDGV; 8 9 public Form1() 10 { 11 InitializeComponent(); 12 } 13 14 private void Form1_Load(object sender, EventArgs e) 15 { 16 // Assembly.EntryPoint.Invoke()するとAssembly.Load()したやつにスレッドを占有されちゃうのでサブスレッドを生成 17 new Thread(new ThreadStart( RunApp)); 18 } 19 20 private void RunApp() 21 { 22 // このプログラムのプロジェクトからexeファイルを参照したtargetAppって名前のWindows Formアプリを立ち上げる 23 Assembly assemblyTargetApp = Assembly.Load("targetApp"); 24 assemblyTargetApp.EntryPoint.Invoke(null, new object[0]); 25 } 26 27 private void button1_Click(object sender, EventArgs e) 28 { 29 FormCollection fc = Application.OpenForms; 30 // FormCollectionには自分も含まれちゃうので外部操作を行いたいアプリの親フォームを捜してあげる 31 Form targetForm = null; 32 foreach(Form f in fc) 33 { 34 // 外部操作を行いたいアプリのFormのTextプロパティに"targetApp"が登録されてる前提 35 if (f.Text == "targetApp") 36 { 37 targetForm = f; 38 break; 39 } 40 } 41 // 必ず見つかる(確信) 42 foreach (Control c in targetForm.Controls) 43 { 44 if (c is DataGridView) 45 { 46 string msg; 47 DataGridView dgv = (DataGridView)c; 48 foreach( DataGridViewRow r in dgv.Rows) 49 foreach( DataGridViewCell c in r.cells) 50 msg += c.Value.ToString() + "\n"; // DataGridViewはDataGridViewCells.Value==nullなセルが発生することがあるけどここでは無視 51 52 Messagebox.Show(msg); 53 } 54 else if(c is Button) 55 { 56 c.Invoke(b.PerformClick.GetType, EventArgs.Empty); // まだ動いてないけどこれもやりたいので一応 57 } 58 } 59} 60
ToDo:
Application.Idleを使ってコントロールをメンバに保持
ButtonやMenuStripを操作できるように調査
前提・実現したいこと
C#を用いて作成したアプリケーションから、既存のアプリでDataGridView
を用いて表示されている内容を取得したい。
既存のアプリのButton
をSendMessage
でクリックしたり、TextBox
の内容を取得したりするアプリケーションを開発中です。
言い方を変えればウィンドウハンドル頼りで他アプリを乗っ取る自動実験用アプリのようなものを実運用で使おうとしています。
既存のアプリはC#をベースにサードパーティのActiveXやOCXを子ダイアログにちりばめたマルチダイアログなアプリです。
既存のアプリの操作や情報取得にはFindWindowEx()
やGetWindowText()
などWinAPIを利用しています。
その既存のアプリの中で(おそらく)DataGridView
コントロールで表示をしている部分があったのでDataGridViewCell
の内容を取得しなくてはならなくなりました。
ところが仮に作ってみたテスト用アプリをMicrosft Spy++で見てみたところ、
DataGridView
コントロールには子ウィンドウがなく、DataGridViewCell
の内容を覗き見る方法に行き詰ってしまいました。
Webにもこれといった情報が見つけられず、途方にくれているような状態です。
こういう方針でなら除き見る方法があるよ、などの情報をご教授いただきたいです。
投げっぱなしな質問ですが皆さんのご経験から問題解決のヒントを分けて頂けたら大変助かります。
今分かっていること
テスト用に作成したプログラム上のDataGridView
をSPI++で見たときのクラス名
WindowsForms10.Window.8.app.0.141b42a_r14_ad1
既存アプリのDataGridView
らしきコントロールのクラス名
WindowsForms10.Window.8.app.0.141b42a_r14_ad1
-
DataGridViewは.NET独自の描画でありWin32 APIが役に立たない。
-
社外品のアプリであり直接改造ができない。
-
すでにDataGridView以外の代理操作はウィンドウハンドラで作ってありあまり変更したくない。
-
運用上の開発案件であり、(残念ながら)お客も(私も)この方法でなんら問題がないものと思い込んでいるため(嫌な予感はするが)既存ソフトの上から覆いかぶさって人間の操作を自動化する
###行動方針
- 既存のアプリを参照により開発アプリに取り込んで操作する
課題:DataGridView以外の操作はウィンドウハンドラ経由で行っていたが、参照を利用して開発アプリのプロセスに取り込むため全て変更する必要がある。
利点:既存アプリを乗っ取る形になるためウィンドウハンドラを利用する方法より色々手出しできるようになる?
- Active Accessibilityを利用する
課題:(往々にあることだけど)肝心の関数の引数がことごとく理解不能。
利点:ほかプロセスから手出しするため今までどおりの方針を維持できる。
補足情報(FW/ツールのバージョンなど)
- Windows7 (64bit)
- VisualStudio 2015 (SP1)
- C#



回答2件
あなたの回答
tips
プレビュー