1
- using System ;
2
- using System . Linq ;
3
- using System . Runtime . InteropServices ;
4
- using NLog ;
1
+ using System . Runtime . InteropServices ;
5
2
using Rubberduck . VBEditor . SafeComWrappers ;
6
3
using Rubberduck . VBEditor . SafeComWrappers . Abstract ;
7
4
8
5
namespace Rubberduck . VBEditor . Application
9
6
{
10
7
[ ComVisible ( false ) ]
11
- public abstract class HostApplicationBase < TApplication > : IHostApplication
8
+ public abstract class HostApplicationBase < TApplication > : SafeComWrapper < TApplication > , IHostApplication
12
9
where TApplication : class
13
10
{
14
- private static readonly Logger _logger = LogManager . GetCurrentClassLogger ( ) ;
15
-
16
- protected readonly TApplication Application ;
17
11
protected HostApplicationBase ( string applicationName )
12
+ : base ( ApplicationFomComReflection ( applicationName ) )
18
13
{
19
14
ApplicationName = applicationName ;
15
+ }
16
+
17
+ protected HostApplicationBase ( IVBE vbe , string applicationName )
18
+ : base ( ApplicationFomVbe ( vbe , applicationName ) )
19
+ {
20
+ ApplicationName = applicationName ;
21
+ }
20
22
23
+ private static TApplication ApplicationFomComReflection ( string applicationName )
24
+ {
25
+ TApplication application ;
21
26
try
22
27
{
23
- Application = ( TApplication ) Marshal . GetActiveObject ( $ "{ applicationName } .Application") ;
28
+ application = ( TApplication ) Marshal . GetActiveObject ( $ "{ applicationName } .Application") ;
24
29
}
25
30
catch ( COMException )
26
31
{
27
- Application = null ; // unit tests don't need it anyway.
32
+ application = null ; // unit tests don't need it anyway.
28
33
}
34
+ return application ;
29
35
}
30
36
31
- protected HostApplicationBase ( IVBE vbe , string applicationName )
37
+ private static TApplication ApplicationFomVbe ( IVBE vbe , string applicationName )
32
38
{
33
- ApplicationName = applicationName ;
34
-
39
+ TApplication application ;
35
40
try
36
41
{
37
42
var appProperty = ApplicationPropertyFromDocumentModule ( vbe ) ;
38
43
if ( appProperty != null )
39
44
{
40
- Application = ( TApplication ) appProperty . Object ;
45
+ application = ( TApplication ) appProperty . Object ;
41
46
}
42
47
else
43
48
{
44
- Application = ( TApplication ) Marshal . GetActiveObject ( $ "{ applicationName } .Application") ;
49
+ application = ( TApplication ) Marshal . GetActiveObject ( $ "{ applicationName } .Application") ;
45
50
}
46
-
51
+
47
52
}
48
53
catch ( COMException )
49
54
{
50
- Application = null ; // unit tests don't need it anyway.
55
+ application = null ; // unit tests don't need it anyway.
51
56
}
57
+ return application ;
52
58
}
53
59
54
60
private static IProperty ApplicationPropertyFromDocumentModule ( IVBE vbe )
@@ -105,10 +111,7 @@ private static IProperty ApplicationPropertyFromDocumentModule(IVBE vbe)
105
111
}
106
112
}
107
113
108
- ~ HostApplicationBase ( )
109
- {
110
- Dispose ( false ) ;
111
- }
114
+ protected TApplication Application => Target ;
112
115
113
116
public string ApplicationName { get ; }
114
117
@@ -119,99 +122,19 @@ public virtual object Run(string name, params object[] args)
119
122
return null ;
120
123
}
121
124
122
- private int ? _rcwReferenceCount ;
123
- public void Release ( bool final = false )
125
+ public override bool Equals ( ISafeComWrapper < TApplication > other )
124
126
{
125
- if ( HasBeenReleased )
126
- {
127
- _logger . Warn ( $ "Tried to release an application object type { this . GetType ( ) } that had already been released.") ;
128
- return ;
129
- }
130
- if ( Application == null )
131
- {
132
- _rcwReferenceCount = 0 ;
133
- _logger . Warn ( $ "Tried to release an application object that was null.") ;
134
- return ;
135
- }
136
-
137
- if ( ! Marshal . IsComObject ( Application ) )
138
- {
139
- _rcwReferenceCount = 0 ;
140
- _logger . Warn ( $ "Tried to release an application objects of type { this . GetType ( ) } that is not a COM object.") ;
141
- return ;
142
- }
143
-
144
- try
145
- {
146
- if ( final )
147
- {
148
- _rcwReferenceCount = Marshal . FinalReleaseComObject ( Application ) ;
149
- if ( HasBeenReleased )
150
- {
151
- _logger . Trace ( $ "Final released application object of type { this . GetType ( ) } .") ;
152
- }
153
- else
154
- {
155
- _logger . Warn ( $ "Final released application object of type { this . GetType ( ) } did not release the object: remaining reference count is { _rcwReferenceCount } .") ;
156
- }
157
- }
158
- else
159
- {
160
- _rcwReferenceCount = Marshal . ReleaseComObject ( Application ) ;
161
- if ( _rcwReferenceCount >= 0 )
162
- {
163
- _logger . Trace ( $ "Released application object of type { this . GetType ( ) } with remaining reference count { _rcwReferenceCount } .") ;
164
- }
165
- else
166
- {
167
- _logger . Warn ( $ "Released application object of type { this . GetType ( ) } whose underlying RCW has already been released from outside the SafeComWrapper.") ;
168
- }
169
- }
170
- }
171
- catch ( COMException exception )
172
- {
173
- var logMessage = $ "Failed to release application object of type { this . GetType ( ) } .";
174
- if ( _rcwReferenceCount . HasValue )
175
- {
176
- logMessage = logMessage + $ "The previous reference count has been { _rcwReferenceCount } .";
177
- }
178
- else
179
- {
180
- logMessage = logMessage + "There has not yet been an attempt to release the application object." ;
181
- }
182
-
183
- _logger . Warn ( exception , logMessage ) ;
184
- }
127
+ return IsEqualIfNull ( other ) || ( other != null && ReferenceEquals ( other . Target , Target ) ) ;
185
128
}
186
129
187
- public bool HasBeenReleased => _rcwReferenceCount <= 0 ;
188
-
189
- public void Dispose ( )
130
+ public override int GetHashCode ( )
190
131
{
191
- Dispose ( true ) ;
192
- GC . SuppressFinalize ( this ) ;
132
+ return IsWrappingNullReference ? 0 : HashCode . Compute ( Target ) ;
193
133
}
194
134
195
- private bool _disposed ;
196
- protected virtual void Dispose ( bool disposing )
135
+ ~ HostApplicationBase ( )
197
136
{
198
- if ( _disposed )
199
- {
200
- return ;
201
- }
202
-
203
- // clean up managed resources
204
- if ( Application != null && ! HasBeenReleased )
205
- {
206
- Release ( ) ;
207
- }
208
-
209
- if ( disposing )
210
- {
211
- // we don't have any managed resources to clean up right now.
212
- }
213
-
214
- _disposed = true ;
137
+ Dispose ( false ) ;
215
138
}
216
139
}
217
140
}
0 commit comments