Added ability to ShellAssociations from ShellItem and improved readability of exception handlers for ERROR_* conditions

pull/211/head
dahall 2021-01-24 19:01:13 -07:00
parent 0a1609d06a
commit 31f9a112e5
3 changed files with 34 additions and 8 deletions

View File

@ -1,5 +1,6 @@
using NUnit.Framework;
using System;
using Vanara.PInvoke.Tests;
using static Vanara.PInvoke.Shell32;
namespace Vanara.Windows.Shell.Tests
@ -16,6 +17,19 @@ namespace Vanara.Windows.Shell.Tests
Assert.That(sha.Handlers, Has.One.Property("UIName").EqualTo("Excel"));
}
[Test]
public void ExamineShellItemAssoc()
{
using var shi = ShellItem.Open(TestCaseSources.TempDir);
var sha = shi.Association;
sha.WriteValues();
foreach (var h in sha.Handlers)
{
TestContext.WriteLine(new string('=', 40));
h.WriteValues();
}
}
[Test]
public void ReadProgIDTest()
{

View File

@ -15,6 +15,11 @@ namespace Vanara.Windows.Shell
{
private IQueryAssociations qassoc;
/// <summary>Initializes a new instance of the <see cref="ShellAssociation"/> class.</summary>
/// <param name="pQA">The IQueryAssociations instance to use.</param>
/// <param name="ext">The optional file extension. This should be in the ".ext" format.</param>
internal ShellAssociation(IQueryAssociations pQA, string ext) : this(ext) => qassoc = pQA;
/// <summary>Initializes a new instance of the <see cref="ShellAssociation"/> class.</summary>
/// <param name="ext">The file extension. This should be in the ".ext" format.</param>
private ShellAssociation(string ext) => Extension = ext;
@ -69,7 +74,7 @@ namespace Vanara.Windows.Shell
if (SHAssocEnumHandlers(Extension, ASSOC_FILTER.ASSOC_FILTER_NONE, out var ieah).Failed)
return (IReadOnlyList<ShellAssociationHandler>)new List<ShellAssociationHandler>();
using var pieah = ComReleaserFactory.Create(ieah);
var e = new Vanara.Collections.IEnumFromCom<IAssocHandler>(ieah.Next, () => { });
var e = new Collections.IEnumFromCom<IAssocHandler>(ieah.Next, () => { });
return (IReadOnlyList<ShellAssociationHandler>)e.Select(i => new ShellAssociationHandler(i)).ToList();
}
}
@ -116,7 +121,7 @@ namespace Vanara.Windows.Shell
/// <summary>Gets the command verbs for this file association.</summary>
/// <value>Returns a <see cref="IReadOnlyDictionary{TKey, TValue}"/> value.</value>
public IReadOnlyDictionary<string, CommandVerb> Verbs => throw new NotImplementedException(); // TODO
public IReadOnlyDictionary<string, CommandVerb> Verbs => null; //throw new NotImplementedException(); // TODO
/// <summary>Initializes a new instance of the <see cref="ShellAssociation"/> class based on the supplied executable name.</summary>
/// <param name="appExeName">The full path of the application executable.</param>
@ -152,7 +157,7 @@ namespace Vanara.Windows.Shell
/// parameter to <see langword="null"/> if it is not used.
/// </param>
/// <returns>A value that, when this method returns successfully, receives the requested data value.</returns>
public Vanara.InteropServices.SafeCoTaskMemHandle GetData(ASSOCDATA data, string extra = null)
public SafeCoTaskMemHandle GetData(ASSOCDATA data, string extra = null)
{
try
{
@ -160,11 +165,11 @@ namespace Vanara.Windows.Shell
var sz = 0U;
qassoc.GetData(flags, data, extra, default, ref sz);
if (sz == 0) return null;
var ret = new Vanara.InteropServices.SafeCoTaskMemHandle(sz);
var ret = new SafeCoTaskMemHandle(sz);
qassoc.GetData(flags, data, extra, ret, ref sz);
return ret;
}
catch (System.Runtime.InteropServices.COMException e) when (e.ErrorCode == (HRESULT)(Win32Error)Win32Error.ERROR_NO_ASSOCIATION)
catch (System.Runtime.InteropServices.COMException e) when (e.ErrorCode == HRESULT.HRESULT_FROM_WIN32(Win32Error.ERROR_NO_ASSOCIATION))
{
return null;
}
@ -204,7 +209,7 @@ namespace Vanara.Windows.Shell
qassoc.GetString(flags, astr, extra, sb, ref sz);
return sb.ToString();
}
catch (System.Runtime.InteropServices.COMException e) when (e.ErrorCode == (HRESULT)(Win32Error)Win32Error.ERROR_NO_ASSOCIATION)
catch (System.Runtime.InteropServices.COMException e) when (e.ErrorCode == HRESULT.HRESULT_FROM_WIN32(Win32Error.ERROR_NO_ASSOCIATION))
{
return null;
}

View File

@ -403,6 +403,11 @@ namespace Vanara.Windows.Shell
remove { ((INotifyPropertyChanged)Properties).PropertyChanged -= value; }
}
/// <summary>Gets the associations defined in the registry for this shell item.</summary>
/// <value>The shell associations.</value>
public ShellAssociation Association =>
new ShellAssociation(GetHandler<IQueryAssociations>(BHID.BHID_AssociationArray), FileInfo?.Extension);
/// <summary>Gets the attributes for the Shell item.</summary>
/// <value>The attributes of the Shell item.</value>
public ShellItemAttribute Attributes => (ShellItemAttribute)(iShellItem?.GetAttributes((SFGAO)0xFFFFFFFF) ?? 0);
@ -817,11 +822,13 @@ namespace Vanara.Windows.Shell
internal static string GetStringValue(Action<StringBuilder, int> method, int buffSize = MAX_PATH)
{
var ret = new StringBuilder(buffSize);
while (true)
{
var ret = new StringBuilder(buffSize, buffSize);
try { method(ret, ret.Capacity); }
catch (COMException ex) { if (ex.ErrorCode == unchecked((int)0x8007007A) || ex.ErrorCode == unchecked((int)0x800700EA) || buffSize <= 8192) buffSize *= 2; else throw; }
catch (COMException ex) when (ex.ErrorCode == HRESULT.HRESULT_FROM_WIN32(Win32Error.ERROR_INSUFFICIENT_BUFFER) ||
ex.ErrorCode == HRESULT.HRESULT_FROM_WIN32(Win32Error.ERROR_MORE_DATA) || ret.Capacity <= 8192)
{ ret.Capacity *= 2; }
return ret.ToString();
}
}