diff --git a/src/Squirrel/ShellFile.cs b/src/Squirrel/ShellFile.cs index 3e84bacc0..c69214245 100644 --- a/src/Squirrel/ShellFile.cs +++ b/src/Squirrel/ShellFile.cs @@ -69,6 +69,44 @@ public static PropVariant FromString(string str) return pv; } + + public static PropVariant FromGuid(Guid guid) + { + byte[] bytes = guid.ToByteArray(); + var pv = new PropVariant() { + variantType = 72, // VT_CLSID + pointerValue = Marshal.AllocCoTaskMem(bytes.Length), + }; + Marshal.Copy(bytes, 0, pv.pointerValue, bytes.Length); + + return pv; + } + + /// + /// Called to properly clean up the memory referenced by a PropVariant instance. + /// + [DllImport("ole32.dll")] + private extern static int PropVariantClear(ref PropVariant pvar); + + /// + /// Called to clear the PropVariant's referenced and local memory. + /// + /// + /// You must call Clear to avoid memory leaks. + /// + public void Clear() + { + // Can't pass "this" by ref, so make a copy to call PropVariantClear with + PropVariant tmp = this; + PropVariantClear(ref tmp); + + // Since we couldn't pass "this" by ref, we need to clear the member fields manually + // NOTE: PropVariantClear already freed heap data for us, so we are just setting + // our references to null. + variantType = (short)VarEnum.VT_EMPTY; + Reserved1 = Reserved2 = Reserved3 = 0; + pointerValue = IntPtr.Zero; + } } [StructLayout(LayoutKind.Sequential)] @@ -885,11 +923,30 @@ public void SetAppUserModelId(string appId) /// Sets the ToastActivatorCLSID /// public void SetToastActivatorCLSID(string clsid) + { + var guid = Guid.Parse(clsid); + SetToastActivatorCLSID(guid); + } + + /// + /// Sets the ToastActivatorCLSID + /// + public void SetToastActivatorCLSID(Guid clsid) { var propStore = (IPropertyStore)linkW; + var pkey = PROPERTYKEY.PKEY_AppUserModel_ToastActivatorCLSID; - var str = PropVariant.FromString (clsid); - propStore.SetValue(ref pkey, ref str); + + var varGuid = PropVariant.FromGuid(clsid); + try { + int errCode = propStore.SetValue(ref pkey, ref varGuid); + Marshal.ThrowExceptionForHR(errCode); + + errCode = propStore.Commit(); + Marshal.ThrowExceptionForHR(errCode); + } finally { + varGuid.Clear(); + } } ///