@@ -156,92 +156,142 @@ private static IMalloc GetMalloc()
156
156
157
157
public static void ExecuteContextMenuItem ( string fileName , uint menuItemId )
158
158
{
159
- var malloc = GetMalloc ( ) ;
160
- var hr = SHParseDisplayName ( fileName , IntPtr . Zero , out var pidl , 0 , out _ ) ;
161
- if ( hr != 0 ) throw new Exception ( "SHParseDisplayName failed" ) ;
159
+ IMalloc malloc = null ;
160
+ IntPtr originalPidl = IntPtr . Zero ;
161
+ IntPtr pShellFolder = IntPtr . Zero ;
162
+ IntPtr pContextMenu = IntPtr . Zero ;
163
+ IntPtr hMenu = IntPtr . Zero ;
164
+ IContextMenu contextMenu = null ;
165
+ IShellFolder shellFolder = null ;
162
166
163
- var originalPidl = pidl ;
167
+ try
168
+ {
169
+ malloc = GetMalloc ( ) ;
170
+ var hr = SHParseDisplayName ( fileName , IntPtr . Zero , out var pidl , 0 , out _ ) ;
171
+ if ( hr != 0 ) throw new Exception ( "SHParseDisplayName failed" ) ;
164
172
165
- var guid = typeof ( IShellFolder ) . GUID ;
166
- hr = SHBindToParent ( pidl , guid , out var pShellFolder , ref pidl ) ;
167
- if ( hr != 0 ) throw new Exception ( "SHBindToParent failed" ) ;
173
+ originalPidl = pidl ;
168
174
169
- var shellFolder = ( IShellFolder ) Marshal . GetTypedObjectForIUnknown ( pShellFolder , typeof ( IShellFolder ) ) ;
170
- hr = shellFolder . GetUIObjectOf (
171
- IntPtr . Zero , 1 , new [ ] { pidl } , typeof ( IContextMenu ) . GUID , IntPtr . Zero , out var pContextMenu
172
- ) ;
173
- if ( hr != 0 ) throw new Exception ( "GetUIObjectOf failed" ) ;
175
+ var guid = typeof ( IShellFolder ) . GUID ;
176
+ hr = SHBindToParent ( pidl , guid , out pShellFolder , ref pidl ) ;
177
+ if ( hr != 0 ) throw new Exception ( "SHBindToParent failed" ) ;
174
178
175
- var contextMenu = ( IContextMenu ) Marshal . GetTypedObjectForIUnknown ( pContextMenu , typeof ( IContextMenu ) ) ;
179
+ shellFolder = ( IShellFolder ) Marshal . GetTypedObjectForIUnknown ( pShellFolder , typeof ( IShellFolder ) ) ;
180
+ hr = shellFolder . GetUIObjectOf (
181
+ IntPtr . Zero , 1 , new [ ] { pidl } , typeof ( IContextMenu ) . GUID , IntPtr . Zero , out pContextMenu
182
+ ) ;
183
+ if ( hr != 0 ) throw new Exception ( "GetUIObjectOf failed" ) ;
176
184
177
- var hMenu = CreatePopupMenu ( ) ;
178
- contextMenu . QueryContextMenu ( hMenu , 0 , ContextMenuStartId , ContextMenuEndId , ( uint ) ContextMenuFlags . Normal ) ;
185
+ contextMenu = ( IContextMenu ) Marshal . GetTypedObjectForIUnknown ( pContextMenu , typeof ( IContextMenu ) ) ;
179
186
180
- var directory = Path . GetDirectoryName ( fileName ) ;
181
- var invokeCommandInfo = new CMINVOKECOMMANDINFO
182
- {
183
- cbSize = ( uint ) Marshal . SizeOf ( typeof ( CMINVOKECOMMANDINFO ) ) ,
184
- fMask = ( uint ) ContextMenuInvokeCommandFlags . Unicode ,
185
- hwnd = IntPtr . Zero ,
186
- lpVerb = ( IntPtr ) ( menuItemId - ContextMenuStartId ) ,
187
- lpParameters = null ,
188
- lpDirectory = directory ?? "" ,
189
- nShow = 1 ,
190
- hIcon = IntPtr . Zero ,
191
- } ;
192
-
193
- hr = contextMenu . InvokeCommand ( ref invokeCommandInfo ) ;
194
- if ( hr != 0 )
195
- {
196
- throw new Exception ( $ "InvokeCommand failed with code { hr : X} ") ;
187
+ hMenu = CreatePopupMenu ( ) ;
188
+ contextMenu . QueryContextMenu ( hMenu , 0 , ContextMenuStartId , ContextMenuEndId , ( uint ) ContextMenuFlags . Normal ) ;
189
+
190
+ var directory = Path . GetDirectoryName ( fileName ) ;
191
+ var invokeCommandInfo = new CMINVOKECOMMANDINFO
192
+ {
193
+ cbSize = ( uint ) Marshal . SizeOf ( typeof ( CMINVOKECOMMANDINFO ) ) ,
194
+ fMask = ( uint ) ContextMenuInvokeCommandFlags . Unicode ,
195
+ hwnd = IntPtr . Zero ,
196
+ lpVerb = ( IntPtr ) ( menuItemId - ContextMenuStartId ) ,
197
+ lpParameters = null ,
198
+ lpDirectory = directory ?? "" ,
199
+ nShow = 1 ,
200
+ hIcon = IntPtr . Zero ,
201
+ } ;
202
+
203
+ hr = contextMenu . InvokeCommand ( ref invokeCommandInfo ) ;
204
+ if ( hr != 0 )
205
+ {
206
+ throw new Exception ( $ "InvokeCommand failed with code { hr : X} ") ;
207
+ }
197
208
}
209
+ finally
210
+ {
211
+ if ( hMenu != IntPtr . Zero )
212
+ DestroyMenu ( hMenu ) ;
213
+
214
+ if ( contextMenu != null )
215
+ Marshal . ReleaseComObject ( contextMenu ) ;
198
216
199
- DestroyMenu ( hMenu ) ;
200
- Marshal . ReleaseComObject ( contextMenu ) ;
201
- Marshal . ReleaseComObject ( shellFolder ) ;
217
+ if ( pContextMenu != IntPtr . Zero )
218
+ Marshal . Release ( pContextMenu ) ;
202
219
203
- if ( originalPidl != IntPtr . Zero )
204
- malloc . Free ( originalPidl ) ;
220
+ if ( shellFolder != null )
221
+ Marshal . ReleaseComObject ( shellFolder ) ;
205
222
206
- Marshal . ReleaseComObject ( malloc ) ;
223
+ if ( pShellFolder != IntPtr . Zero )
224
+ Marshal . Release ( pShellFolder ) ;
225
+
226
+ if ( originalPidl != IntPtr . Zero )
227
+ malloc ? . Free ( originalPidl ) ;
228
+
229
+ if ( malloc != null )
230
+ Marshal . ReleaseComObject ( malloc ) ;
231
+ }
207
232
}
208
233
209
234
public static List < ContextMenuItem > GetContextMenuWithIcons ( string filePath )
210
235
{
211
- var malloc = GetMalloc ( ) ;
212
- var hr = SHParseDisplayName ( filePath , IntPtr . Zero , out var pidl , 0 , out _ ) ;
213
- if ( hr != 0 ) throw new Exception ( "SHParseDisplayName failed" ) ;
236
+ IMalloc malloc = null ;
237
+ IntPtr originalPidl = IntPtr . Zero ;
238
+ IntPtr pShellFolder = IntPtr . Zero ;
239
+ IShellFolder shellFolder = null ;
240
+ IntPtr pContextMenu = IntPtr . Zero ;
241
+ IContextMenu contextMenu = null ;
242
+ IntPtr hMenu = IntPtr . Zero ;
214
243
215
- var originalPidl = pidl ;
244
+ try
245
+ {
246
+ malloc = GetMalloc ( ) ;
247
+ var hr = SHParseDisplayName ( filePath , IntPtr . Zero , out var pidl , 0 , out _ ) ;
248
+ if ( hr != 0 ) throw new Exception ( "SHParseDisplayName failed" ) ;
216
249
217
- var guid = typeof ( IShellFolder ) . GUID ;
218
- hr = SHBindToParent ( pidl , guid , out var pShellFolder , ref pidl ) ;
219
- if ( hr != 0 ) throw new Exception ( "SHBindToParent failed" ) ;
250
+ originalPidl = pidl ;
220
251
221
- var shellFolder = ( IShellFolder ) Marshal . GetTypedObjectForIUnknown ( pShellFolder , typeof ( IShellFolder ) ) ;
222
- hr = shellFolder . GetUIObjectOf (
223
- IntPtr . Zero , 1 , new [ ] { pidl } , typeof ( IContextMenu ) . GUID , IntPtr . Zero , out var pContextMenu
224
- ) ;
225
- if ( hr != 0 ) throw new Exception ( "GetUIObjectOf failed" ) ;
252
+ var guid = typeof ( IShellFolder ) . GUID ;
253
+ hr = SHBindToParent ( pidl , guid , out pShellFolder , ref pidl ) ;
254
+ if ( hr != 0 ) throw new Exception ( "SHBindToParent failed" ) ;
226
255
227
- var contextMenu = ( IContextMenu ) Marshal . GetTypedObjectForIUnknown ( pContextMenu , typeof ( IContextMenu ) ) ;
256
+ shellFolder = ( IShellFolder ) Marshal . GetTypedObjectForIUnknown ( pShellFolder , typeof ( IShellFolder ) ) ;
257
+ hr = shellFolder . GetUIObjectOf (
258
+ IntPtr . Zero , 1 , new [ ] { pidl } , typeof ( IContextMenu ) . GUID , IntPtr . Zero , out pContextMenu
259
+ ) ;
260
+ if ( hr != 0 ) throw new Exception ( "GetUIObjectOf failed" ) ;
228
261
229
- var hMenu = CreatePopupMenu ( ) ;
230
- contextMenu . QueryContextMenu ( hMenu , 0 , ContextMenuStartId , ContextMenuEndId , ( uint ) ContextMenuFlags . Normal ) ;
262
+ contextMenu = ( IContextMenu ) Marshal . GetTypedObjectForIUnknown ( pContextMenu , typeof ( IContextMenu ) ) ;
231
263
232
- var menuItems = new List < ContextMenuItem > ( ) ;
233
- ProcessMenuWithIcons ( hMenu , contextMenu , menuItems ) ;
264
+ hMenu = CreatePopupMenu ( ) ;
265
+ contextMenu . QueryContextMenu ( hMenu , 0 , ContextMenuStartId , ContextMenuEndId , ( uint ) ContextMenuFlags . Normal ) ;
234
266
235
- DestroyMenu ( hMenu ) ;
236
- Marshal . ReleaseComObject ( contextMenu ) ;
237
- Marshal . ReleaseComObject ( shellFolder ) ;
267
+ var menuItems = new List < ContextMenuItem > ( ) ;
268
+ ProcessMenuWithIcons ( hMenu , contextMenu , menuItems ) ;
238
269
239
- if ( originalPidl != IntPtr . Zero )
240
- malloc . Free ( originalPidl ) ;
270
+ return menuItems ;
271
+ }
272
+ finally
273
+ {
274
+ if ( hMenu != IntPtr . Zero )
275
+ DestroyMenu ( hMenu ) ;
276
+
277
+ if ( contextMenu != null )
278
+ Marshal . ReleaseComObject ( contextMenu ) ;
279
+
280
+ if ( pContextMenu != IntPtr . Zero )
281
+ Marshal . Release ( pContextMenu ) ;
241
282
242
- Marshal . ReleaseComObject ( malloc ) ;
283
+ if ( shellFolder != null )
284
+ Marshal . ReleaseComObject ( shellFolder ) ;
243
285
244
- return menuItems ;
286
+ if ( pShellFolder != IntPtr . Zero )
287
+ Marshal . Release ( pShellFolder ) ;
288
+
289
+ if ( originalPidl != IntPtr . Zero )
290
+ malloc ? . Free ( originalPidl ) ;
291
+
292
+ if ( malloc != null )
293
+ Marshal . ReleaseComObject ( malloc ) ;
294
+ }
245
295
}
246
296
247
297
0 commit comments