回答編集履歴

3

サンプルを見つけたので追記

2019/05/06 09:38

投稿

atata0319
atata0319

スコア881

test CHANGED
@@ -24,20 +24,26 @@
24
24
 
25
25
 
26
26
 
27
- ### 2.API をフックする。
28
-
29
- CoGetClassObject、CoCreateInstance、CoCreateInstanceEx をフックして該当の CLSID が指定されている場合に自分で作成したコンポーネント(or クラスファクトリ)を返すようにしてみてください。これはレジストリ登録が不要なので次にお勧めです。
30
-
31
-
32
-
33
- なお、XP を前提としない場合、CoCreateInstanceFromApp もフック対象となります。また、ProgID からの変換が必要である場合、CLSIDFromProgID および CLSIDFromProgIDEx もフック対象となります。今回のファイルダイアログに関しては上記は不要です。
34
-
35
-
36
-
37
- ### .クラスファクトリを登録する。
27
+ ### .クラスファクトリを登録する。
38
28
 
39
29
  CoRegisterClassObject で独自に作成したコンポーネントのクラスファクトリをスレッド毎に登録することでも実現可能です。レジストリに登録されている設定よりも優先されるので、実は一番お勧めしたいのですが、アパートメント毎ではなくスレッド毎に CoRegisterClassObject を呼び出す必要があるので、意外と手間がかかります。DllMain 内では KERNEL32 の処理しか呼んではいけないことになっているので、DLL_THREAD_ATTACH で登録するというのは避けた方が良いかなとは思います。
40
30
 
41
31
 
42
32
 
43
33
  ドキュメントには記載がありませんが、DLL_THREAD_ATTACH で CoRegisterInitializeSpy で IInitializeSpy をインストールして、IInitializeSpy::PostInitialize メソッドで CoRegisterClassObject するとうまくいくと思います。CoInitialize はウィンドウ作成したりするので、DLL_THREAD_ATTACH 内で使うとハングすることがままありますが、CoRegisterInitializeSpy で遅延させれば回避可能かと思います。
34
+
35
+ ちょうどスタックオーバーフローで同じ回答を見つけました。
36
+
37
+ [https://stackoverflow.com/questions/24993611/define-a-com-class-that-is-only-createable-from-the-same-exe-where-it-is-registe](https://stackoverflow.com/questions/24993611/define-a-com-class-that-is-only-createable-from-the-same-exe-where-it-is-registe)
38
+
39
+ スタックオーバーフローの文面ではアパートメント毎にという記載がありますが、CoRegisterClassObject はスレッド毎に必要であったと記憶しています。ただし、今回は GUI を持ったコンポーネントを登録するので、MTA ではないので違いは出ません。
40
+
41
+
42
+
43
+ ### 3.API をフックする。
44
+
45
+ CoGetClassObject、CoCreateInstance、CoCreateInstanceEx をフックして該当の CLSID が指定されている場合に自分で作成したコンポーネント(or クラスファクトリ)を返すようにしてみてください。~~これはレジストリ登録が不要なので次にお勧めです。~~ 2番の実現性が高くなったのでお勧めとしては3番目にします。
46
+
47
+
48
+
49
+ なお、XP を前提としない場合、CoCreateInstanceFromApp もフック対象となります。また、ProgID からの変換が必要である場合、CLSIDFromProgID および CLSIDFromProgIDEx もフック対象となります。今回のファイルダイアログに関しては上記は不要です。

2

CoRegisterInitializeSpy について追記

2019/05/06 09:38

投稿

atata0319
atata0319

スコア881

test CHANGED
@@ -6,23 +6,25 @@
6
6
 
7
7
 
8
8
 
9
+ ---
10
+
9
11
 
10
12
 
11
13
  > IFileDialogが実装されていなければ、システムに実装を追加する方法
12
14
 
13
15
 
14
16
 
15
- 一般的に 3 種類方法があります。
17
+ 一般的に以下に挙げる 3 種類方法があります。
16
18
 
17
19
 
18
20
 
19
- 1.レジストリに登録する。
21
+ ### 1.レジストリに登録する。
20
22
 
21
23
  インストールされていない前提であれば上記の CLSID を持った DLL を通常の COM と同様にレジストリ登録するのが最も単純で良いかと思います。
22
24
 
23
25
 
24
26
 
25
- 2.API をフックする。
27
+ ### 2.API をフックする。
26
28
 
27
29
  CoGetClassObject、CoCreateInstance、CoCreateInstanceEx をフックして該当の CLSID が指定されている場合に自分で作成したコンポーネント(or クラスファクトリ)を返すようにしてみてください。これはレジストリ登録が不要なので次にお勧めです。
28
30
 
@@ -32,6 +34,10 @@
32
34
 
33
35
 
34
36
 
35
- 3.クラスファクトリを登録する。
37
+ ### 3.クラスファクトリを登録する。
36
38
 
37
39
  CoRegisterClassObject で独自に作成したコンポーネントのクラスファクトリをスレッド毎に登録することでも実現可能です。レジストリに登録されている設定よりも優先されるので、実は一番お勧めしたいのですが、アパートメント毎ではなくスレッド毎に CoRegisterClassObject を呼び出す必要があるので、意外と手間がかかります。DllMain 内では KERNEL32 の処理しか呼んではいけないことになっているので、DLL_THREAD_ATTACH で登録するというのは避けた方が良いかなとは思います。
40
+
41
+
42
+
43
+ ドキュメントには記載がありませんが、DLL_THREAD_ATTACH で CoRegisterInitializeSpy で IInitializeSpy をインストールして、IInitializeSpy::PostInitialize メソッドで CoRegisterClassObject するとうまくいくと思います。CoInitialize はウィンドウ作成したりするので、DLL_THREAD_ATTACH 内で使うとハングすることがままありますが、CoRegisterInitializeSpy で遅延させれば回避可能かと思います。

1

情報が足りない部分を追記

2019/05/06 08:53

投稿

atata0319
atata0319

スコア881

test CHANGED
@@ -28,6 +28,10 @@
28
28
 
29
29
 
30
30
 
31
+ なお、XP を前提としない場合、CoCreateInstanceFromApp もフック対象となります。また、ProgID からの変換が必要である場合、CLSIDFromProgID および CLSIDFromProgIDEx もフック対象となります。今回のファイルダイアログに関しては上記は不要です。
32
+
33
+
34
+
31
35
  3.クラスファクトリを登録する。
32
36
 
33
37
  CoRegisterClassObject で独自に作成したコンポーネントのクラスファクトリをスレッド毎に登録することでも実現可能です。レジストリに登録されている設定よりも優先されるので、実は一番お勧めしたいのですが、アパートメント毎ではなくスレッド毎に CoRegisterClassObject を呼び出す必要があるので、意外と手間がかかります。DllMain 内では KERNEL32 の処理しか呼んではいけないことになっているので、DLL_THREAD_ATTACH で登録するというのは避けた方が良いかなとは思います。