Skip to content

Instantly share code, notes, and snippets.

@hexagr
Created May 29, 2025 18:12
Show Gist options
  • Select an option

  • Save hexagr/adfaf53ede2dd49fb75b376118a7d522 to your computer and use it in GitHub Desktop.

Select an option

Save hexagr/adfaf53ede2dd49fb75b376118a7d522 to your computer and use it in GitHub Desktop.
Toast Notifications on Windows 11
$ShortcutPath = "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\MyToastApp.lnk"
$TargetPath = "C:\Path\To\YourApp.exe"
$AppUserModelID = "Your.App.ID"
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
[ComImport]
[Guid("00021401-0000-0000-C000-000000000046")]
class ShellLink {}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("000214F9-0000-0000-C000-000000000046")]
interface IShellLinkW {
void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder pszFile, int cchMaxPath, out IntPtr pfd, int fFlags);
void GetIDList(out IntPtr ppidl);
void SetIDList(IntPtr pidl);
void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder pszName, int cchMaxName);
void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder pszDir, int cchMaxPath);
void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder pszArgs, int cchMaxPath);
void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
void GetHotkey(out short pwHotkey);
void SetHotkey(short wHotkey);
void GetShowCmd(out int piShowCmd);
void SetShowCmd(int iShowCmd);
void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder pszIconPath, int cchIconPath, out int piIcon);
void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
void Resolve(IntPtr hwnd, int fFlags);
void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
}
[ComImport]
[Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IPropertyStore {
void GetCount(out uint cProps);
void GetAt(uint iProp, out PROPERTYKEY pkey);
void GetValue(ref PROPERTYKEY key, out PROPVARIANT pv);
void SetValue(ref PROPERTYKEY key, ref PROPVARIANT pv);
void Commit();
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
struct PROPERTYKEY {
public Guid fmtid;
public uint pid;
}
[StructLayout(LayoutKind.Explicit)]
struct PROPVARIANT {
[FieldOffset(0)]
public ushort vt;
[FieldOffset(8)]
public IntPtr pszVal;
public static PROPVARIANT FromString(string value) {
var pv = new PROPVARIANT();
pv.vt = 31; // VT_LPWSTR
pv.pszVal = Marshal.StringToCoTaskMemUni(value);
return pv;
}
}
public static class ShellLinkHelper {
static readonly Guid PKEY_AppUserModel_ID_fmtid = new Guid("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3");
const uint PKEY_AppUserModel_ID_pid = 5;
public static void CreateShortcut(string shortcutPath, string exePath, string appId) {
var link = (IShellLinkW)new ShellLink();
link.SetPath(exePath);
var store = (IPropertyStore)link;
var key = new PROPERTYKEY() { fmtid = PKEY_AppUserModel_ID_fmtid, pid = PKEY_AppUserModel_ID_pid };
var pv = PROPVARIANT.FromString(appId);
store.SetValue(ref key, ref pv);
store.Commit();
var file = (IPersistFile)link;
file.Save(shortcutPath, false);
}
}
"@ -Language CSharp
# Call the helper from PowerShell
[ShellLinkHelper]::CreateShortcut($ShortcutPath, $TargetPath, $AppUserModelID)
Write-Host "Shortcut created at $ShortcutPath with AppUserModelID = $AppUserModelID"
#include <windows.h>
#include <wrl/client.h>
#include <wrl/wrappers/corewrappers.h>
#include <windows.ui.notifications.h>
#include <winrt/base.h>
#include <winrt/Windows.Data.Xml.Dom.h>
#include <winrt/Windows.UI.Notifications.h>
#include <string>
#include <iostream>
#include <shobjidl.h>
#pragma comment(lib, "Shell32.lib")
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace winrt;
using namespace winrt::Windows::Data::Xml::Dom;
using namespace winrt::Windows::UI::Notifications;
int main() {
RoInitialize(RO_INIT_SINGLETHREADED);
// Set AppUserModelID
SetCurrentProcessExplicitAppUserModelID(L"Your.App.ID");
// Create Toast Notifier
auto toastNotifier = ToastNotificationManager::CreateToastNotifier(L"Your.App.ID");
// Create XML content
XmlDocument toastXml;
try {
std::wstring xmlString = L"<toast><visual><binding template='ToastGeneric'><text>Hello from C++!</text></binding></visual></toast>";
toastXml.LoadXml(xmlString);
}
catch (const hresult_error& ex) {
std::wcerr << L"Failed to load XML: " << ex.message().c_str() << std::endl;
RoUninitialize();
return 1;
}
// Create Toast Notification
auto toast = ToastNotification(toastXml);
// Show Toast
toastNotifier.Show(toast);
RoUninitialize();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment