mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-03-30 10:19:51 +08:00
138 lines
4.4 KiB
C#
138 lines
4.4 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace MicaSetup.Shell.Dialogs;
|
|
|
|
#pragma warning disable CS8618
|
|
|
|
public class ShellPropertyWriter : IDisposable
|
|
{
|
|
internal IPropertyStore writablePropStore;
|
|
|
|
private ShellObject parentShellObject;
|
|
|
|
internal ShellPropertyWriter(ShellObject parent)
|
|
{
|
|
ParentShellObject = parent;
|
|
|
|
var guid = new Guid(ShellIIDGuid.IPropertyStore);
|
|
|
|
try
|
|
{
|
|
var hr = ParentShellObject.NativeShellItem2.GetPropertyStore(
|
|
GetPropertyStoreOptions.ReadWrite,
|
|
ref guid,
|
|
out writablePropStore);
|
|
|
|
if (!CoreErrorHelper.Succeeded(hr))
|
|
{
|
|
throw new PropertySystemException(LocalizedMessages.ShellPropertyUnableToGetWritableProperty,
|
|
Marshal.GetExceptionForHR(hr));
|
|
}
|
|
else
|
|
{
|
|
if (ParentShellObject.NativePropertyStore == null)
|
|
{
|
|
ParentShellObject.NativePropertyStore = writablePropStore;
|
|
}
|
|
}
|
|
}
|
|
catch (InvalidComObjectException e)
|
|
{
|
|
throw new PropertySystemException(LocalizedMessages.ShellPropertyUnableToGetWritableProperty, e);
|
|
}
|
|
catch (InvalidCastException)
|
|
{
|
|
throw new PropertySystemException(LocalizedMessages.ShellPropertyUnableToGetWritableProperty);
|
|
}
|
|
}
|
|
|
|
~ShellPropertyWriter()
|
|
{
|
|
Dispose(false);
|
|
}
|
|
|
|
protected ShellObject ParentShellObject
|
|
{
|
|
get => parentShellObject;
|
|
private set => parentShellObject = value;
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
if (writablePropStore != null)
|
|
{
|
|
writablePropStore.Commit();
|
|
|
|
Marshal.ReleaseComObject(writablePropStore);
|
|
writablePropStore = null!;
|
|
}
|
|
|
|
ParentShellObject.NativePropertyStore = null!;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
public void WriteProperty(PropertyKey key, object value) => WriteProperty(key, value, true);
|
|
|
|
public void WriteProperty(PropertyKey key, object value, bool allowTruncatedValue)
|
|
{
|
|
if (writablePropStore == null)
|
|
throw new InvalidOperationException("Writeable store has been closed.");
|
|
|
|
using var propVar = PropVariant.FromObject(value);
|
|
var result = writablePropStore.SetValue(ref key, propVar);
|
|
|
|
if (!allowTruncatedValue && ((int)result == ShellNativeMethods.InPlaceStringTruncated))
|
|
{
|
|
Marshal.ReleaseComObject(writablePropStore);
|
|
writablePropStore = null!;
|
|
|
|
throw new ArgumentOutOfRangeException("value", LocalizedMessages.ShellPropertyValueTruncated);
|
|
}
|
|
|
|
if (!CoreErrorHelper.Succeeded(result))
|
|
{
|
|
throw new PropertySystemException(LocalizedMessages.ShellPropertySetValue, Marshal.GetExceptionForHR((int)result));
|
|
}
|
|
}
|
|
|
|
public void WriteProperty(string canonicalName, object value) => WriteProperty(canonicalName, value, true);
|
|
|
|
public void WriteProperty(string canonicalName, object value, bool allowTruncatedValue)
|
|
{
|
|
var result = PropertySystemNativeMethods.PSGetPropertyKeyFromName(canonicalName, out var propKey);
|
|
|
|
if (!CoreErrorHelper.Succeeded(result))
|
|
{
|
|
throw new ArgumentException(
|
|
LocalizedMessages.ShellInvalidCanonicalName,
|
|
Marshal.GetExceptionForHR(result));
|
|
}
|
|
|
|
WriteProperty(propKey, value, allowTruncatedValue);
|
|
}
|
|
|
|
public void WriteProperty(IShellProperty shellProperty, object value) => WriteProperty(shellProperty, value, true);
|
|
|
|
public void WriteProperty(IShellProperty shellProperty, object value, bool allowTruncatedValue)
|
|
{
|
|
if (shellProperty == null) { throw new ArgumentNullException("shellProperty"); }
|
|
WriteProperty(shellProperty.PropertyKey, value, allowTruncatedValue);
|
|
}
|
|
|
|
public void WriteProperty<T>(ShellProperty<T> shellProperty, T value) => WriteProperty<T>(shellProperty, value, true);
|
|
|
|
public void WriteProperty<T>(ShellProperty<T> shellProperty, T value, bool allowTruncatedValue)
|
|
{
|
|
if (shellProperty == null) { throw new ArgumentNullException("shellProperty"); }
|
|
WriteProperty(shellProperty.PropertyKey, value!, allowTruncatedValue);
|
|
}
|
|
|
|
protected virtual void Dispose(bool disposing) => Close();
|
|
}
|