From c7aa663ae05bc736931f54e39ca5d1c29b16a92c Mon Sep 17 00:00:00 2001 From: Kan-Ru Chen Date: Tue, 31 Dec 2024 00:28:03 +0900 Subject: [PATCH] feat: make tsfreg uninstall more robust against failures --- tsfreg/src/main.rs | 233 +++++++++++++++++++++++---------------------- 1 file changed, 117 insertions(+), 116 deletions(-) diff --git a/tsfreg/src/main.rs b/tsfreg/src/main.rs index a9a9658..1886de3 100644 --- a/tsfreg/src/main.rs +++ b/tsfreg/src/main.rs @@ -1,116 +1,117 @@ -#![windows_subsystem = "windows"] - -use std::{env, process}; - -use windows::{ - core::*, - Win32::{Globalization::*, System::Com::*, UI::TextServices::*}, -}; - -const CHEWING_TSF_CLSID: GUID = GUID::from_u128(0x13F2EF08_575C_4D8C_88E0_F67BB8052B84); -const CHEWING_PROFILE_GUID: GUID = GUID::from_u128(0xCE45F71D_CE79_41D1_967D_640B65A380E3); - -fn register(icon_path: String) -> Result<()> { - unsafe { - let input_processor_profile_mgr: ITfInputProcessorProfileMgr = - CoCreateInstance(&CLSID_TF_InputProcessorProfiles, None, CLSCTX_INPROC_SERVER)?; - - let mut lcid = LocaleNameToLCID(w!("zh-Hant-TW"), 0); - if lcid == 0 { - lcid = LocaleNameToLCID(w!("zh-TW"), 0); - } - - let pw_icon_path = icon_path.encode_utf16().collect::>(); - - input_processor_profile_mgr.RegisterProfile( - &CHEWING_TSF_CLSID, - lcid as u16, - &CHEWING_PROFILE_GUID, - w!("新酷音輸入法").as_wide(), - &pw_icon_path, - 0, - None, - 0, - true, - 0, - )?; - - let category_manager: ITfCategoryMgr = - CoCreateInstance(&CLSID_TF_CategoryMgr, None, CLSCTX_INPROC_SERVER)?; - - category_manager.RegisterCategory( - &CHEWING_TSF_CLSID, - &GUID_TFCAT_TIP_KEYBOARD, - &CHEWING_TSF_CLSID, - )?; - category_manager.RegisterCategory( - &CHEWING_TSF_CLSID, - &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, - &CHEWING_TSF_CLSID, - )?; - category_manager.RegisterCategory( - &CHEWING_TSF_CLSID, - &GUID_TFCAT_TIPCAP_INPUTMODECOMPARTMENT, - &CHEWING_TSF_CLSID, - )?; - category_manager.RegisterCategory( - &CHEWING_TSF_CLSID, - &GUID_TFCAT_TIPCAP_UIELEMENTENABLED, - &CHEWING_TSF_CLSID, - )?; - - category_manager.RegisterCategory( - &CHEWING_TSF_CLSID, - &GUID_TFCAT_TIPCAP_IMMERSIVESUPPORT, - &CHEWING_TSF_CLSID, - )?; - category_manager.RegisterCategory( - &CHEWING_TSF_CLSID, - &GUID_TFCAT_TIPCAP_SYSTRAYSUPPORT, - &CHEWING_TSF_CLSID, - )?; - } - Ok(()) -} - -fn unregister() -> Result<()> { - unsafe { - let input_processor_profile_mgr: ITfInputProcessorProfileMgr = - CoCreateInstance(&CLSID_TF_InputProcessorProfiles, None, CLSCTX_INPROC_SERVER)?; - - let mut lcid = LocaleNameToLCID(w!("zh-Hant-TW"), 0); - if lcid == 0 { - lcid = LocaleNameToLCID(w!("zh-TW"), 0); - } - - input_processor_profile_mgr.UnregisterProfile( - &CHEWING_TSF_CLSID, - lcid as u16, - &CHEWING_PROFILE_GUID, - 0, - )?; - } - Ok(()) -} - -fn main() -> Result<()> { - unsafe { - CoInitializeEx(None, COINIT_APARTMENTTHREADED).ok()?; - - if env::args().len() == 1 { - println!("Usage:"); - println!(" tsfreg -r 註冊輸入法"); - println!(" tsfreg -u 取消註冊"); - process::exit(1); - } - - if let Some("-r") = env::args().nth(1).as_ref().map(|s| s.as_str()) { - let icon_path = env::args().nth(2).expect("缺少 IconPath"); - register(icon_path)?; - } else { - unregister()?; - } - } - - Ok(()) -} +use std::{env, process}; + +use windows::{ + core::*, + Win32::{Globalization::*, System::Com::*, UI::TextServices::*}, +}; + +const CHEWING_TSF_CLSID: GUID = GUID::from_u128(0x13F2EF08_575C_4D8C_88E0_F67BB8052B84); +const CHEWING_PROFILE_GUID: GUID = GUID::from_u128(0xCE45F71D_CE79_41D1_967D_640B65A380E3); + +fn register(icon_path: String) -> Result<()> { + unsafe { + let input_processor_profile_mgr: ITfInputProcessorProfileMgr = + CoCreateInstance(&CLSID_TF_InputProcessorProfiles, None, CLSCTX_INPROC_SERVER)?; + + let mut lcid = LocaleNameToLCID(w!("zh-Hant-TW"), 0); + if lcid == 0 { + lcid = LocaleNameToLCID(w!("zh-TW"), 0); + } + + let pw_icon_path = icon_path.encode_utf16().collect::>(); + + input_processor_profile_mgr.RegisterProfile( + &CHEWING_TSF_CLSID, + lcid as u16, + &CHEWING_PROFILE_GUID, + w!("新酷音輸入法").as_wide(), + &pw_icon_path, + 0, + None, + 0, + true, + 0, + )?; + + let category_manager: ITfCategoryMgr = + CoCreateInstance(&CLSID_TF_CategoryMgr, None, CLSCTX_INPROC_SERVER)?; + + category_manager.RegisterCategory( + &CHEWING_TSF_CLSID, + &GUID_TFCAT_TIP_KEYBOARD, + &CHEWING_TSF_CLSID, + )?; + category_manager.RegisterCategory( + &CHEWING_TSF_CLSID, + &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, + &CHEWING_TSF_CLSID, + )?; + category_manager.RegisterCategory( + &CHEWING_TSF_CLSID, + &GUID_TFCAT_TIPCAP_INPUTMODECOMPARTMENT, + &CHEWING_TSF_CLSID, + )?; + category_manager.RegisterCategory( + &CHEWING_TSF_CLSID, + &GUID_TFCAT_TIPCAP_UIELEMENTENABLED, + &CHEWING_TSF_CLSID, + )?; + + category_manager.RegisterCategory( + &CHEWING_TSF_CLSID, + &GUID_TFCAT_TIPCAP_IMMERSIVESUPPORT, + &CHEWING_TSF_CLSID, + )?; + category_manager.RegisterCategory( + &CHEWING_TSF_CLSID, + &GUID_TFCAT_TIPCAP_SYSTRAYSUPPORT, + &CHEWING_TSF_CLSID, + )?; + } + Ok(()) +} + +fn unregister() -> Result<()> { + unsafe { + let input_processor_profile_mgr: ITfInputProcessorProfileMgr = + CoCreateInstance(&CLSID_TF_InputProcessorProfiles, None, CLSCTX_INPROC_SERVER)?; + + let mut lcid = LocaleNameToLCID(w!("zh-Hant-TW"), 0); + if lcid == 0 { + lcid = LocaleNameToLCID(w!("zh-TW"), 0); + } + + input_processor_profile_mgr.UnregisterProfile( + &CHEWING_TSF_CLSID, + lcid as u16, + &CHEWING_PROFILE_GUID, + 0, + )?; + } + Ok(()) +} + +fn main() -> Result<()> { + unsafe { + CoInitializeEx(None, COINIT_APARTMENTTHREADED).ok()?; + + if env::args().len() == 1 { + println!("Usage:"); + println!(" tsfreg -r 註冊輸入法"); + println!(" tsfreg -u 取消註冊"); + process::exit(1); + } + + if let Some("-r") = env::args().nth(1).as_ref().map(|s| s.as_str()) { + let icon_path = env::args().nth(2).expect("缺少 IconPath"); + register(icon_path)?; + } else { + if let Err(err) = unregister() { + println!("警告:無法解除輸入法註冊,反安裝可能無法正常完成。"); + println!("錯誤訊息:{:?}", err); + } + } + } + + Ok(()) +}