Browse Source

Fix CA1806/Improve exception handling

pull/3619/head
Siegfried Pammer 4 months ago
parent
commit
217c72d311
  1. 2
      ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs
  2. 90
      ILSpy/Util/ShellHelper.cs

2
ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs

@ -178,7 +178,7 @@ namespace ICSharpCode.ILSpy
else else
{ {
if (isFile && File.Exists(path)) if (isFile && File.Exists(path))
output.AddButton(null, Resources.OpenExplorer, delegate { ShellHelper.OpenFolderAndSelectItems(new[] { path }); }); output.AddButton(null, Resources.OpenExplorer, delegate { ShellHelper.OpenFolderAndSelectItem(path); });
else else
output.AddButton(null, Resources.OpenExplorer, delegate { ShellHelper.OpenFolder(path); }); output.AddButton(null, Resources.OpenExplorer, delegate { ShellHelper.OpenFolder(path); });
} }

90
ILSpy/Util/ShellHelper.cs

@ -17,11 +17,12 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Runtime.InteropServices;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Runtime.InteropServices;
#pragma warning disable CA1060 // Move pinvokes to native methods class #pragma warning disable CA1060 // Move pinvokes to native methods class
@ -43,6 +44,7 @@ namespace ICSharpCode.ILSpy.Util
public static void OpenFolder(string folderPath) public static void OpenFolder(string folderPath)
{ {
nint folderPidl = IntPtr.Zero;
try try
{ {
if (string.IsNullOrEmpty(folderPath)) if (string.IsNullOrEmpty(folderPath))
@ -50,31 +52,40 @@ namespace ICSharpCode.ILSpy.Util
if (!Directory.Exists(folderPath)) if (!Directory.Exists(folderPath))
return; return;
IntPtr folderPidl = IntPtr.Zero; int hr = SHParseDisplayName(folderPath, IntPtr.Zero, out folderPidl, 0, out var attrs);
uint attrs; Marshal.ThrowExceptionForHR(hr);
int hr = SHParseDisplayName(folderPath, IntPtr.Zero, out folderPidl, 0, out attrs);
if (hr == 0 && folderPidl != IntPtr.Zero) hr = SHOpenFolderAndSelectItems(folderPidl, 0, null, 0);
Marshal.ThrowExceptionForHR(hr);
}
catch (Exception ex) when (ex is COMException or Win32Exception)
{ {
SHOpenFolderAndSelectItems(folderPidl, 0, null, 0); // fall back to Process.Start
CoTaskMemFree(folderPidl); OpenFolderFallback(folderPath);
} }
else finally
{ {
// fallback if (folderPidl != IntPtr.Zero)
Process.Start(new ProcessStartInfo { FileName = folderPath, UseShellExecute = true }); CoTaskMemFree(folderPidl);
}
} }
static void OpenFolderFallback(string path)
{
try
{
Process.Start(new ProcessStartInfo { FileName = path, UseShellExecute = true });
} }
catch catch (Exception)
{ {
// ignore // Process.Start can throw several errors (not all of them documented),
// just ignore all of them.
} }
} }
public static void OpenFolderAndSelectItem(string path) public static void OpenFolderAndSelectItem(string path)
{ {
// Reuse the multi-item implementation for single item selection to avoid duplication. // Reuse the multi-item implementation for single item selection to avoid duplication.
try
{
if (string.IsNullOrEmpty(path)) if (string.IsNullOrEmpty(path))
return; return;
if (Directory.Exists(path)) if (Directory.Exists(path))
@ -86,17 +97,10 @@ namespace ICSharpCode.ILSpy.Util
if (!File.Exists(path)) if (!File.Exists(path))
return; return;
OpenFolderAndSelectItems(new[] { path }); OpenFolderAndSelectItems(path);
}
catch
{
// ignore
}
} }
public static void OpenFolderAndSelectItems(IEnumerable<string> paths) public static void OpenFolderAndSelectItems(params IEnumerable<string> paths)
{
try
{ {
if (paths == null) if (paths == null)
return; return;
@ -105,31 +109,25 @@ namespace ICSharpCode.ILSpy.Util
if (files.Count == 0) if (files.Count == 0)
return; return;
var groups = files.GroupBy(p => Path.GetDirectoryName(p)); var itemPidlAllocs = new List<IntPtr>();
foreach (var group in groups) var relativePidls = new List<IntPtr>();
foreach (var group in files.GroupBy(Path.GetDirectoryName))
{ {
string folder = group.Key; string folder = group.Key;
if (string.IsNullOrEmpty(folder) || !Directory.Exists(folder)) if (string.IsNullOrEmpty(folder) || !Directory.Exists(folder))
continue; continue;
IntPtr folderPidl = IntPtr.Zero; IntPtr folderPidl = IntPtr.Zero;
uint attrs;
int hrFolder = SHParseDisplayName(folder, IntPtr.Zero, out folderPidl, 0, out attrs);
if (hrFolder != 0 || folderPidl == IntPtr.Zero)
{
// fallback: open folder normally
OpenFolder(folder);
continue;
}
var itemPidlAllocs = new List<IntPtr>();
var relativePidls = new List<IntPtr>();
try try
{ {
int hrFolder = SHParseDisplayName(folder, IntPtr.Zero, out folderPidl, 0, out uint attrs);
Marshal.ThrowExceptionForHR(hrFolder);
foreach (var file in group) foreach (var file in group)
{ {
IntPtr itemPidl = IntPtr.Zero; int hrItem = SHParseDisplayName(file, IntPtr.Zero, out var itemPidl, 0, out attrs);
int hrItem = SHParseDisplayName(file, IntPtr.Zero, out itemPidl, 0, out attrs);
if (hrItem == 0 && itemPidl != IntPtr.Zero) if (hrItem == 0 && itemPidl != IntPtr.Zero)
{ {
IntPtr relative = ILFindLastID(itemPidl); IntPtr relative = ILFindLastID(itemPidl);
@ -146,7 +144,8 @@ namespace ICSharpCode.ILSpy.Util
if (relativePidls.Count > 0) if (relativePidls.Count > 0)
{ {
SHOpenFolderAndSelectItems(folderPidl, (uint)relativePidls.Count, relativePidls.ToArray(), 0); int hr = SHOpenFolderAndSelectItems(folderPidl, (uint)relativePidls.Count, relativePidls.ToArray(), 0);
Marshal.ThrowExceptionForHR(hr);
} }
else else
{ {
@ -154,19 +153,22 @@ namespace ICSharpCode.ILSpy.Util
OpenFolder(folder); OpenFolder(folder);
} }
} }
catch (Exception ex) when (ex is COMException or Win32Exception)
{
// fall back to Process.Start
OpenFolderFallback(folder);
}
finally finally
{ {
foreach (var p in itemPidlAllocs) foreach (var p in itemPidlAllocs)
CoTaskMemFree(p); CoTaskMemFree(p);
if (folderPidl != IntPtr.Zero) if (folderPidl != IntPtr.Zero)
CoTaskMemFree(folderPidl); CoTaskMemFree(folderPidl);
itemPidlAllocs.Clear();
relativePidls.Clear();
} }
} }
} }
catch
{
// ignore
}
}
} }
} }

Loading…
Cancel
Save