我有一个可离线和在线使用的clickonce应用程序。它用于打开和编辑.xml文件。如果它们的路径作为启动参数(如
)给出,它可以打开.xml文件"c:Path\Name.appref-ms" "Xmlpath\name.xml"
使用控制台窗口。
现在我想添加一个注册表项,这样我就可以右键单击任何.xml并在打开下找到我的应用程序。我在 HKCR \ .xml \ OpenWithProgids 下添加了一个密钥,并在 HKCR \ myapp.xml \ shell \ open \ command 中添加了一个密钥,但我无法弄清楚,如何编写该命令。我的理解是,该命令应该与我在控制台窗口中可以使用的命令相同,所以我试过
"c:Path\Name.appref-ms" "%1"
这似乎不起作用,我也尝试过很多不同用途的引号但总是得到
name.xml is not a valid win 32 application
作为错误消息。有谁知道,如果我想做什么是可能的,怎么做?
附加信息:
- 如果我使用它可以使用的可执行文件,只是看起来不能用clickonce thingy
- 应用程序使用如下参数:
if(AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData!=null)
{
//Do something
}
答案 0 :(得分:0)
首先,这是结果,shell扩展的外观如何(灰显其他扩展):
您需要在注册表中添加一些条目。我为它写了一个注册表助手类。您可以使用它,也可以只应用密钥。您只需调整名称并调用方法EnsureRegistryKeyIntegrity()
。注意:我添加了一个配置开关来启用或禁用shell扩展功能。如果你不想把你的shell搞得太多,这可能会很有用。
一个重要事情:您需要使用管理员权限运行该方法,否则您将收到异常。
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
}