2014-05-19 85 views
1

我有一個ClickOnce應用程序可用脫機和聯機。它用於打開和編輯.xml文件。它可以打開.xml文件,如果它們的路徑被指定爲啓動參數,如打開的文件類型(XML)與ClickOnce應用程序

"c:Path\Name.appref-ms" "Xmlpath\name.xml" 

使用控制檯窗口。

現在我想添加一個註冊表項,所以我可以右鍵點擊任何.xml並找到我的應用程序打開。我下,加入一鍵HKCR \ .XML \ OpenWithProgids和關鍵HKCR \ myapp.xml \殼\開放\命令但我無法弄清楚,如何使這一命令。我的理解是,該命令應該是相同的一個,我可以在控制檯窗口中使用,所以我嘗試

"c:Path\Name.appref-ms" "%1" 

這似乎並沒有工作,雖然,我也嘗試了很多quotationmarks的不同用途,但總是得到

name.xml is not a valid win 32 application 

作爲錯誤消息。有誰知道,如果我想要做什麼是可能的以及如何做到這一點?


附加信息:
- 如果我使用它工作的可執行文件,好像不能用的ClickOnce做啄

- 應用程序使用這樣的說法:

if(AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData!=null) 
{ 
    //Do something 
} 
+0

我已經在我的一個私人應用程序中解決了這個問題。如果你不想浪費時間,可以等到我回家 - 從現在開始約90分鐘 - 我會後一個工作爲你解答:) – Herdo

+0

@Herdo謝謝你,把你的時間,你的幫助是非常apprechiated: ) – Pasoe

+0

沒問題。只有一個問題:'''它可以運行的可執行文件'「 - 你的意思是與ClickOnce應用程序相關聯的註冊文件類型?像 – Herdo

回答

0

首先,這是結果,外殼擴展可看怎麼樣(變灰其他分機): enter image description here

你需要幾個條目添加到註冊表中。我爲它寫了一個註冊表幫助類。你可以使用這個,或者只是應用鍵。您只需要調整名稱並調用方法EnsureRegistryKeyIntegrity()即可。注意:我添加了一個配置開關來啓用或禁用外殼擴展功能。如果你不想炸燬你的外殼,這可能是有用的。

一個重要事情:您需要以管理員權限運行該方法,否則您將收到一個異常。

internal static class RegistryHelper 
{ 
    //////////////////////////////////////////////// 
    #region Statics 

    /// <summary> 
    /// A dictionary of registry roots and their subkeys to handle. 
    /// </summary> 
    private static readonly Dictionary<RegistryHive, string[]> RegistryKeys = new Dictionary<RegistryHive, string[]> 
    { 
     { 
      RegistryHive.ClassesRoot, 
      new [] 
      { 
       @"*\shell\QuickHash", 
       @"*\shell\QuickHash\command", 
       @"Directory\shell\QuickHash", 
       @"Directory\shell\QuickHash\command" 
      } 
     } 
    }; 

    /// <summary> 
    /// The registry default value for the command keys. 
    /// </summary> 
    private static readonly string RegistryCommandValue; 

    #endregion 

    //////////////////////////////////////////////// 
    #region Constructors 

    static RegistryHelper() 
    { 
     RegistryCommandValue = String.Format("\"{0}\" /file \"%1\"", Assembly.GetExecutingAssembly().Location); 
    } 

    #endregion 

    //////////////////////////////////////////////// 
    #region Public Methods 

    /// <summary> 
    /// Ensures that all required registry keys exist and adjusts their values if required. 
    /// </summary> 
    public static void EnsureRegistryKeyIntegrity() 
    { 
     foreach (var registryRoot in RegistryKeys.Keys) 
     { 
      foreach (var registryKeyName in RegistryKeys[registryRoot]) 
      { 
       if (((App)Application.Current).Config.EnableExplorerContextMenu) 
       { 
        var regKey = GetOrAddKey(registryRoot, registryKeyName); 
        AdjustKey(regKey); 
        regKey.Close(); 
       } 
       else 
       { 
        DeleteKey(registryRoot, registryKeyName); 
       } 
      } 
     } 
    } 

    #endregion 

    //////////////////////////////////////////////// 
    #region Private Methods 

    /// <summary> 
    /// Gets or adds a specific key for a specific registry root. 
    /// </summary> 
    /// <param name="registryRoot">The registry root.</param> 
    /// <param name="registryKeyName">The registry key.</param> 
    /// <returns>Returns the gotten or added registry key.</returns> 
    private static RegistryKey GetOrAddKey(RegistryHive registryRoot, string registryKeyName) 
    { 
     switch (registryRoot) 
     { 
      case RegistryHive.ClassesRoot: 
       return Registry.ClassesRoot.OpenSubKey(registryKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.SetValue) ?? 
         Registry.ClassesRoot.CreateSubKey(registryKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree); 
      case RegistryHive.CurrentUser: 
       return Registry.CurrentUser.OpenSubKey(registryKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.SetValue) ?? 
         Registry.CurrentUser.CreateSubKey(registryKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree); 
      case RegistryHive.LocalMachine: 
       return Registry.LocalMachine.OpenSubKey(registryKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.SetValue) ?? 
         Registry.LocalMachine.CreateSubKey(registryKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree); 
      case RegistryHive.Users: 
       return Registry.Users.OpenSubKey(registryKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.SetValue) ?? 
         Registry.Users.CreateSubKey(registryKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree); 
      case RegistryHive.PerformanceData: 
       return Registry.PerformanceData.OpenSubKey(registryKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.SetValue) ?? 
         Registry.PerformanceData.CreateSubKey(registryKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree); 
      case RegistryHive.CurrentConfig: 
       return Registry.CurrentConfig.OpenSubKey(registryKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.SetValue) ?? 
         Registry.CurrentConfig.CreateSubKey(registryKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree); 
      case RegistryHive.DynData: 
       // DynData is obsolete 
       return Registry.PerformanceData.OpenSubKey(registryKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.SetValue) ?? 
         Registry.PerformanceData.CreateSubKey(registryKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree); 
      default: 
       throw new ArgumentOutOfRangeException("registryRoot"); 
     } 
    } 

    /// <summary> 
    /// Deletes an unused registry key. 
    /// </summary> 
    /// <param name="registryRoot">The registry root.</param> 
    /// <param name="registryKeyName">The registry key.</param> 
    private static void DeleteKey(RegistryHive registryRoot, string registryKeyName) 
    { 
     const string missingRightsText = "You don't have the permissions to perform this action."; 
     const string missingRightsCaption = "Error"; 
     try 
     { 
      switch (registryRoot) 
      { 
       case RegistryHive.ClassesRoot: 
        Registry.ClassesRoot.DeleteSubKeyTree(registryKeyName, false); 
        break; 
       case RegistryHive.CurrentUser: 
        Registry.CurrentUser.DeleteSubKeyTree(registryKeyName, false); 
        break; 
       case RegistryHive.LocalMachine: 
        Registry.LocalMachine.DeleteSubKeyTree(registryKeyName, false); 
        break; 
       case RegistryHive.Users: 
        Registry.Users.DeleteSubKeyTree(registryKeyName, false); 
        break; 
       case RegistryHive.PerformanceData: 
        Registry.PerformanceData.DeleteSubKeyTree(registryKeyName, false); 
        break; 
       case RegistryHive.CurrentConfig: 
        Registry.CurrentConfig.DeleteSubKeyTree(registryKeyName, false); 
        break; 
       case RegistryHive.DynData: 
        // DynData is obsolete 
        Registry.PerformanceData.DeleteSubKeyTree(registryKeyName, false); 
        break; 
       default: 
        throw new ArgumentOutOfRangeException("registryRoot"); 
      } 
     } 
     catch (SecurityException) 
     { 
      MessageBox.Show(missingRightsText, missingRightsCaption, MessageBoxButton.OK, MessageBoxImage.Error); 
     } 
     catch (UnauthorizedAccessException) 
     { 
      MessageBox.Show(missingRightsText, missingRightsCaption, MessageBoxButton.OK, MessageBoxImage.Error); 
     } 
    } 

    /// <summary> 
    /// Adjusts the registry keys value. 
    /// </summary> 
    /// <param name="regKey">The registry key to adjust.</param> 
    private static void AdjustKey(RegistryKey regKey) 
    { 
     if (regKey.Name.EndsWith("QuickHash")) 
     { 
      SetExplorerShellName(regKey); 
      SetExplorerShellIcon(regKey); 
      return; 
     } 
     if (regKey.Name.EndsWith("command")) 
     { 
      var keyDefaultValue = regKey.GetValue("") as String; 
      if (String.IsNullOrEmpty(keyDefaultValue) 
      || keyDefaultValue != RegistryCommandValue) 
      { 
       regKey.SetValue(null, RegistryCommandValue, RegistryValueKind.String); 
      } 
      return; 
     } 

     throw new NotSupportedException("Given registry key is not supported."); 
    } 

    private static void SetExplorerShellName(RegistryKey regKey) 
    { 
     const string quickHashDisplayName = "Quick Hash"; 
     var keyDefaultValue = regKey.GetValue("") as String; 
     if (String.IsNullOrEmpty(keyDefaultValue) 
      || keyDefaultValue != quickHashDisplayName) 
     { 
      regKey.SetValue(null, quickHashDisplayName, RegistryValueKind.String); 
     } 
    } 

    private static void SetExplorerShellIcon(RegistryKey regKey) 
    { 
     var executingAssembly = (new Uri(Assembly.GetExecutingAssembly().CodeBase)).AbsolutePath; 
     regKey.SetValue("Icon", String.Format("{0},0", executingAssembly)); 
    } 

    #endregion 
} 
+0

我想你的解決方案,但遺憾的是它沒有工作。我仍然得到同樣的錯誤。我想我會嘗試你的方法的一些變化,也許我可以找出一些東西。不過,謝謝你的答案。 – Pasoe

+0

@Pasoe你能請張貼的代碼生成註冊表項/條目? – Herdo

+0

哎呦,我搞砸了。你的解決方案沒有工作,我仍然使用ActivationData而不是字符串[] args – Pasoe

相關問題