Skip to content

Instantly share code, notes, and snippets.

@yume-chan
Last active October 17, 2024 18:29
Show Gist options
  • Save yume-chan/d31c28a7aa702cbef1a1db3e57849534 to your computer and use it in GitHub Desktop.
Save yume-chan/d31c28a7aa702cbef1a1db3e57849534 to your computer and use it in GitHub Desktop.
Rust code to add shortcut with App User Model ID
[target.'cfg(target_os = "windows")'.dependencies.windows]
version = "0.58"
features = [
"Foundation",
"Media",
"Win32_Foundation",
"Win32_Storage_EnhancedStorage",
"Win32_System_LibraryLoader",
"Win32_System_Com",
"Win32_System_Com_StructuredStorage",
"Win32_System_Environment",
"Win32_System_WinRT",
"Win32_System_ProcessStatus",
"Win32_System_Threading",
"Win32_UI_Shell",
"Win32_UI_Shell_PropertiesSystem",
"Storage_Streams",
]
use windows::{
core::{w, Interface, HSTRING, PROPVARIANT},
Win32::{
Foundation::MAX_PATH,
Storage::EnhancedStorage::PKEY_AppUserModel_ID,
System::{
Com::{
CoCreateInstance, CoInitializeEx, IPersistFile,
StructuredStorage::InitPropVariantFromStringAsVector, CLSCTX_INPROC_SERVER,
COINIT_APARTMENTTHREADED,
},
Environment::GetEnvironmentVariableW,
ProcessStatus::GetModuleFileNameExW,
Threading::GetCurrentProcess,
},
UI::Shell::{IShellLinkW, PropertiesSystem::IPropertyStore, ShellLink},
},
};
unsafe {
let mut shortcut_path = [0u16; MAX_PATH as usize];
let len = GetEnvironmentVariableW(w!("APPDATA"), Some(&mut shortcut_path));
let mut shortcut_path = PathBuf::from(OsString::from_wide(&shortcut_path[..len as usize]));
shortcut_path.push(r"Microsoft\Windows\Start Menu\Programs\SMTC Test.lnk");
if !fs::exists(&shortcut_path).unwrap() {
let mut exe_path = [0u16; MAX_PATH as usize];
GetModuleFileNameExW(GetCurrentProcess(), None, exe_path.as_mut_slice());
CoInitializeEx(None, COINIT_APARTMENTTHREADED).unwrap();
let link: IShellLinkW =
CoCreateInstance(&ShellLink, None, CLSCTX_INPROC_SERVER).unwrap();
link.SetPath(&HSTRING::from_wide(&exe_path).unwrap())
.unwrap();
link.SetArguments(w!("")).unwrap();
let property_store: IPropertyStore = link.cast().unwrap();
let app_id_prop_var: PROPVARIANT =
InitPropVariantFromStringAsVector(w!("moe.chensi.test")).unwrap();
property_store
.SetValue(&PKEY_AppUserModel_ID, &app_id_prop_var)
.unwrap();
property_store.Commit().unwrap();
let persist_file: IPersistFile = link.cast().unwrap();
persist_file
.Save(&HSTRING::from(shortcut_path.as_os_str()), true)
.unwrap();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment