Открыть тип файла (xml) с помощью приложения clickonce

1

У меня есть приложение clickonce, доступное офлайн и онлайн. Он используется для открытия и редактирования файлов.xml. Он может открывать файлы.xml, если их путь указан как аргумент запуска, например

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

используя консольное окно.

Теперь я хочу добавить запись в реестр, поэтому я могу щелкнуть любой.xml и найти свое приложение под открытым текстом. Я добавил ключ под HKCR\.xml\OpenWithProgids и ключ HKCR\myapp.xml\shell\open \, но я не могу понять, как это сделать. Я понимаю, что команда должна быть такой же, как и я, которую я могу использовать в окне консоли, поэтому я попробовал

"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 
}
Теги:
registry
clickonce
windows-shell

1 ответ

0
Лучший ответ

Прежде всего, это результат, как может выглядеть оболочка (greyed из других расширений): Изображение 174551

Вам нужно добавить несколько записей в реестр. Я написал для него вспомогательный класс реестра. Вы можете использовать это или просто применить ключи. Вам нужно только настроить имена и вызвать метод 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
    Я попробовал ваше решение, но, к сожалению, оно не сработало. Я все еще получаю ту же ошибку. Я думаю, что попробую несколько вариантов вашего подхода, может быть, я смогу что-нибудь выяснить. Тем не менее, спасибо за ответ.
  • 0
    @Pasoe Можете ли вы опубликовать запись / записи реестра, сгенерированные кодом?
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню