WPF推薦的單例應用程式二
阿新 • • 發佈:2021-08-04
繼續豐富《WPF單例應用程式》,編寫一個類似Word的應用程式,思路與上一篇一致,主要新增以下幾點功能變更:
(1)自定義指定格式檔案:.testDoc字尾檔案;
(2)登錄檔中註冊檔案拓展名.testDoc,並且關聯SingleInstanceApplication.exe程式路徑,實現雙擊.testDoc檔案自動由SingleInstanceApplication.exe開啟,與wold效果類似;
主要注意2點:
//1.註冊新的拓展名 .testDoc string extension = ".testDoc"; string title = "SingleInstanceApplication"; string extensionDescription = "A Test Document"; FileRegistrationHelper.SetFileAssociation( extension, title + "." + extensionDescription);
public class FileRegistrationHelper { public static void SetFileAssociation(string extension, string progID) {// Create extension subkey SetValue(Registry.ClassesRoot, extension, progID); // Create progid subkey string assemblyFullPath = System.Reflection.Assembly.GetExecutingAssembly().Location.Replace("/", @"\"); StringBuilder sbShellEntry = new StringBuilder(); sbShellEntry.AppendFormat("\"{0}\" \"%1\"", assemblyFullPath); SetValue(Registry.ClassesRoot, progID + @"\shell\open\command", sbShellEntry.ToString()); StringBuilder sbDefaultIconEntry = new StringBuilder(); sbDefaultIconEntry.AppendFormat("\"{0}\",0", assemblyFullPath); SetValue(Registry.ClassesRoot, progID + @"\DefaultIcon", sbDefaultIconEntry.ToString()); // Create application subkey SetValue(Registry.ClassesRoot, @"Applications\" + Path.GetFileName(assemblyFullPath), "", "NoOpenWith"); } private static void SetValue(RegistryKey root, string subKey, object keyValue) { SetValue(root, subKey, keyValue, null); } private static void SetValue(RegistryKey root, string subKey, object keyValue, string valueName) { bool hasSubKey = ((subKey != null) && (subKey.Length > 0)); RegistryKey key = root; try { if (hasSubKey) key = root.CreateSubKey(subKey); key.SetValue(valueName, keyValue); } finally { if (hasSubKey && (key != null)) key.Close(); } } }
2.許可權問題,操作登錄檔需要管理員許可權才可以執行
(1)通過app.manifest設定<requestedExecutionLevel level="highestAvailable" />
<?xml version="1.0" encoding="utf-8"?> <asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <assemblyIdentity version="1.0.0.0" name="MyApplication.app" /> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <security> <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> <requestedExecutionLevel level="highestAvailable" /> </requestedPrivileges> <applicationRequestMinimum> <defaultAssemblyRequest permissionSetReference="Custom" /> <PermissionSet Unrestricted="true" ID="Custom" SameSite="site" /> </applicationRequestMinimum> </security> </trustInfo> </asmv1:assembly>
highestAvailable按當前賬號能獲取到的許可權執行(能拿到的最大許可權),而requireAdministrator則是當前使用者必須是管理員許可權才能執行。
如果當前賬戶是管理員賬戶的話,那麼兩者都是可以的通過提升許可權來獲取到管理員許可權執行程式;而如果當前賬戶是Guest的話,那麼highestAvailable則放棄提升許可權而直接執行,而requireAdministrator則允許輸入其他管理員賬戶的密碼來提升許可權。
(2)判斷系統版本及執行許可權處理登錄檔變更
protected override bool OnStartup( Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e) { string extension = ".testDoc"; string title = "SingleInstanceApplication"; string extensionDescription = "A Test Document"; //Vista之後版本才有UAC許可權 Boolean afterVista = (Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major >= 6); if (afterVista) { MessageBox.Show("afterVista"); //判斷當前系統執行許可權是不是管理員許可權 var identity = WindowsIdentity.GetCurrent(); var principal = new WindowsPrincipal(identity); if (principal.IsInRole(WindowsBuiltInRole.Administrator)) { MessageBox.Show("管理員許可權執行"); // 管理員許可權執行才去操作登錄檔 FileRegistrationHelper.SetFileAssociation( extension, title + "." + extensionDescription); } else { MessageBox.Show("普通許可權執行"); } } else { //Vista之前版本沒有UAC安全控制,可以直接操作登錄檔 FileRegistrationHelper.SetFileAssociation( extension, title + "." + extensionDescription); } app = new WpfApp(); app.Run(); return false; }