Last active
October 17, 2024 18:29
-
-
Save yume-chan/d31c28a7aa702cbef1a1db3e57849534 to your computer and use it in GitHub Desktop.
Rust code to add shortcut with App User Model ID
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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", | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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