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 @@ -178,7 +178,7 @@ namespace ICSharpCode.ILSpy
else
{
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
output.AddButton(null, Resources.OpenExplorer, delegate { ShellHelper.OpenFolder(path); });
}

90
ILSpy/Util/ShellHelper.cs

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

Loading…
Cancel
Save