質問編集履歴

4

修正とToDoを追加

2019/06/19 01:41

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -88,7 +88,7 @@
88
88
 
89
89
  // 必ず見つかる(確信)
90
90
 
91
- foreach (Control c in formUITarget.Controls)
91
+ foreach (Control c in targetForm.Controls)
92
92
 
93
93
  {
94
94
 
@@ -128,6 +128,14 @@
128
128
 
129
129
  ```
130
130
 
131
+
132
+
133
+ ToDo:
134
+
135
+ Application.Idleを使ってコントロールをメンバに保持
136
+
137
+ ButtonやMenuStripを操作できるように調査
138
+
131
139
  ### 前提・実現したいこと
132
140
 
133
141
 

3

進捗晒し

2019/06/19 01:41

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -1,5 +1,133 @@
1
1
  よろしくお願いいたします。
2
2
 
3
+ ### 解決コード
4
+
5
+ まだ途中だけど
6
+
7
+ ```c#
8
+
9
+ using System.Threading;
10
+
11
+ using System.Reflection;
12
+
13
+
14
+
15
+ public partial class Form1 : Form
16
+
17
+ {
18
+
19
+ ThreadUITarget m_uiAutomationTargetThread;
20
+
21
+ DataGridView m_uiAutoTargetDGV;
22
+
23
+
24
+
25
+ public Form1()
26
+
27
+ {
28
+
29
+ InitializeComponent();
30
+
31
+ }
32
+
33
+
34
+
35
+ private void Form1_Load(object sender, EventArgs e)
36
+
37
+ {
38
+
39
+ // Assembly.EntryPoint.Invoke()するとAssembly.Load()したやつにスレッドを占有されちゃうのでサブスレッドを生成
40
+
41
+ new Thread(new ThreadStart( RunApp));
42
+
43
+ }
44
+
45
+
46
+
47
+ private void RunApp()
48
+
49
+ {
50
+
51
+ // このプログラムのプロジェクトからexeファイルを参照したtargetAppって名前のWindows Formアプリを立ち上げる
52
+
53
+ Assembly assemblyTargetApp = Assembly.Load("targetApp");
54
+
55
+ assemblyTargetApp.EntryPoint.Invoke(null, new object[0]);
56
+
57
+ }
58
+
59
+
60
+
61
+ private void button1_Click(object sender, EventArgs e)
62
+
63
+ {
64
+
65
+ FormCollection fc = Application.OpenForms;
66
+
67
+ // FormCollectionには自分も含まれちゃうので外部操作を行いたいアプリの親フォームを捜してあげる
68
+
69
+ Form targetForm = null;
70
+
71
+ foreach(Form f in fc)
72
+
73
+ {
74
+
75
+ // 外部操作を行いたいアプリのFormのTextプロパティに"targetApp"が登録されてる前提
76
+
77
+ if (f.Text == "targetApp")
78
+
79
+ {
80
+
81
+ targetForm = f;
82
+
83
+ break;
84
+
85
+ }
86
+
87
+ }
88
+
89
+ // 必ず見つかる(確信)
90
+
91
+ foreach (Control c in formUITarget.Controls)
92
+
93
+ {
94
+
95
+ if (c is DataGridView)
96
+
97
+ {
98
+
99
+ string msg;
100
+
101
+ DataGridView dgv = (DataGridView)c;
102
+
103
+ foreach( DataGridViewRow r in dgv.Rows)
104
+
105
+ foreach( DataGridViewCell c in r.cells)
106
+
107
+ msg += c.Value.ToString() + "\n"; // DataGridViewはDataGridViewCells.Value==nullなセルが発生することがあるけどここでは無視
108
+
109
+
110
+
111
+ Messagebox.Show(msg);
112
+
113
+ }
114
+
115
+ else if(c is Button)
116
+
117
+ {
118
+
119
+ c.Invoke(b.PerformClick.GetType, EventArgs.Empty); // まだ動いてないけどこれもやりたいので一応
120
+
121
+ }
122
+
123
+ }
124
+
125
+ }
126
+
127
+
128
+
129
+ ```
130
+
3
131
  ### 前提・実現したいこと
4
132
 
5
133
 

2

経過を追加

2019/06/19 01:21

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -9,6 +9,10 @@
9
9
 
10
10
 
11
11
  既存のアプリの`Button`を`SendMessage`でクリックしたり、`TextBox`の内容を取得したりするアプリケーションを開発中です。
12
+
13
+ 言い方を変えればウィンドウハンドル頼りで他アプリを乗っ取る自動実験用アプリのようなものを実運用で使おうとしています。
14
+
15
+
12
16
 
13
17
  既存のアプリはC#をベースにサードパーティのActiveXやOCXを子ダイアログにちりばめたマルチダイアログなアプリです。
14
18
 
@@ -58,6 +62,40 @@
58
62
 
59
63
 
60
64
 
65
+ - DataGridViewは.NET独自の描画でありWin32 APIが役に立たない。
66
+
67
+
68
+
69
+ - 社外品のアプリであり直接改造ができない。
70
+
71
+
72
+
73
+ - すでにDataGridView以外の代理操作はウィンドウハンドラで作ってありあまり変更したくない。
74
+
75
+
76
+
77
+ - 運用上の開発案件であり、(残念ながら)お客も(私も)この方法でなんら問題がないものと思い込んでいるため(嫌な予感はするが)既存ソフトの上から覆いかぶさって人間の操作を自動化する
78
+
79
+ ###行動方針
80
+
81
+
82
+
83
+ - 既存のアプリを参照により開発アプリに取り込んで操作する
84
+
85
+
86
+
87
+ 課題:DataGridView以外の操作はウィンドウハンドラ経由で行っていたが、参照を利用して開発アプリのプロセスに取り込むため全て変更する必要がある。
88
+
89
+ 利点:既存アプリを乗っ取る形になるためウィンドウハンドラを利用する方法より色々手出しできるようになる?
90
+
91
+ - Active Accessibilityを利用する
92
+
93
+
94
+
95
+ 課題:(往々にあることだけど)肝心の関数の引数がことごとく理解不能。
96
+
97
+ 利点:ほかプロセスから手出しするため今までどおりの方針を維持できる。
98
+
61
99
  ### 補足情報(FW/ツールのバージョンなど)
62
100
 
63
101
  - Windows7 (64bit)

1

言い訳を追加

2019/06/18 02:38

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -29,6 +29,8 @@
29
29
  Webにもこれといった情報が見つけられず、途方にくれているような状態です。
30
30
 
31
31
  こういう方針でなら除き見る方法があるよ、などの情報をご教授いただきたいです。
32
+
33
+ 投げっぱなしな質問ですが皆さんのご経験から問題解決のヒントを分けて頂けたら大変助かります。
32
34
 
33
35
 
34
36