Подтвердить что ты не робот

Как связать расширение файла с текущим исполняемым файлом в С#

Я хотел бы связать расширение файла с текущим исполняемым файлом в С#. Таким образом, когда пользователь нажимает на файл впоследствии в проводнике, он запускает мой исполняемый файл с данным файлом в качестве первого аргумента. В идеале он также установил значок для указанных расширений файла на значок моего исполняемого файла. Спасибо всем.

4b9b3361

Ответ 1

Не существует API-интерфейса .Net для непосредственного управления ассоциациями файлов, но вы можете использовать классы реестра для чтения и записи ключей, которые вам нужны.

Вам нужно создать ключ под HKEY_CLASSES_ROOT с именем, установленным для расширения вашего файла (например: ".txt" ). Задайте значение по умолчанию этого ключа уникальному имени для вашего типа файла, например "Acme.TextFile". Затем создайте еще один ключ под HKEY_CLASSES_ROOT с именем, установленным в "Acme.TextFile". Добавьте подраздел "DefaultIcon" и установите значение по умолчанию для файла, содержащего значок, который вы хотите использовать для этого типа файла. Добавьте другого брата, называемого "оболочка". Под клавишей "shell" добавьте ключ для каждого действия, которое вы хотите получить через контекстное меню "Проводник", установив значение по умолчанию для каждой клавиши на путь к исполняемому файлу, а затем пробел и "% 1", чтобы представить путь к выбранному файлу.

Например, здесь пример файла реестра для создания связи между TXT файлами и EmEditor:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.txt]
@="emeditor.txt"

[HKEY_CLASSES_ROOT\emeditor.txt]
@="Text Document"

[HKEY_CLASSES_ROOT\emeditor.txt\DefaultIcon]
@="%SystemRoot%\\SysWow64\\imageres.dll,-102"

[HKEY_CLASSES_ROOT\emeditor.txt\shell]

[HKEY_CLASSES_ROOT\emeditor.txt\shell\open]

[HKEY_CLASSES_ROOT\emeditor.txt\shell\open\command]
@="\"C:\\Program Files\\EmEditor\\EMEDITOR.EXE\" \"%1\""

[HKEY_CLASSES_ROOT\emeditor.txt\shell\print]

[HKEY_CLASSES_ROOT\emeditor.txt\shell\print\command]
@="\"C:\\Program Files\\EmEditor\\EMEDITOR.EXE\" /p \"%1\""

Ответ 2

Кроме того, если вы решите пойти в реестре, помните, что текущие ассоциации пользователей находятся под HKEY_CURRENT_USER\Software\Classes. Возможно, лучше добавить ваше приложение вместо локальных классов.

Если ваша программа будет запущена ограниченным пользователем, вы все равно не сможете модифицировать CLASSES_ROOT.

Ответ 3

Если вы используете развертывание ClickOnce, все это обрабатывается для вас (по крайней мере, в VS2008 SP1); просто:

  • Свойства проекта
  • Опубликовать
  • Параметры
  • File Associatons
  • (добавьте все, что вам нужно)

(обратите внимание, что это должно быть полное доверие, предназначено для .NET 3.5 и должно быть установлено для использования в автономном режиме)

См. также MSDN: Как создать ассоциации файлов для приложения ClickOnce

Ответ 4

Вот полный пример:

public class FileAssociation
{
    public string Extension { get; set; }
    public string ProgId { get; set; }
    public string FileTypeDescription { get; set; }
    public string ExecutableFilePath { get; set; }
}

public class FileAssociations
{
    // needed so that Explorer windows get refreshed after the registry is updated
    [System.Runtime.InteropServices.DllImport("Shell32.dll")]
    private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);

    private const int SHCNE_ASSOCCHANGED = 0x8000000;
    private const int SHCNF_FLUSH = 0x1000;

    public static void EnsureAssociationsSet()
    {
        var filePath = Process.GetCurrentProcess().MainModule.FileName;
        EnsureAssociationsSet(
            new FileAssociation
            {
                Extension = ".binlog",
                ProgId = "MSBuildBinaryLog",
                FileTypeDescription = "MSBuild Binary Log",
                ExecutableFilePath = filePath
            },
            new FileAssociation
            {
                Extension = ".buildlog",
                ProgId = "MSBuildStructuredLog",
                FileTypeDescription = "MSBuild Structured Log",
                ExecutableFilePath = filePath
            });
    }

    public static void EnsureAssociationsSet(params FileAssociation[] associations)
    {
        bool madeChanges = false;
        foreach (var association in associations)
        {
            madeChanges |= SetAssociation(
                association.Extension,
                association.ProgId,
                association.FileTypeDescription,
                association.ExecutableFilePath);
        }

        if (madeChanges)
        {
            SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
        }
    }

    public static bool SetAssociation(string extension, string progId, string fileTypeDescription, string applicationFilePath)
    {
        bool madeChanges = false;
        madeChanges |= SetKeyDefaultValue(@"Software\Classes\" + extension, progId);
        madeChanges |= SetKeyDefaultValue(@"Software\Classes\" + progId, fileTypeDescription);
        madeChanges |= SetKeyDefaultValue([email protected]"Software\Classes\{progId}\shell\open\command", "\"" + applicationFilePath + "\" \"%1\"");
        return madeChanges;
    }

    private static bool SetKeyDefaultValue(string keyPath, string value)
    {
        using (var key = Registry.CurrentUser.CreateSubKey(keyPath))
        {
            if (key.GetValue(null) as string != value)
            {
                key.SetValue(null, value);
                return true;
            }
        }

        return false;
    }

Ответ 5

Могут быть конкретные причины, по которым вы не хотите использовать пакет установки для своего проекта, но пакет установки - отличное место для простого выполнения задач настройки приложений, таких как регистрация расширений файлов, добавление ярлыков на рабочем столе и т.д.

Здесь, как создать ассоциацию расширения файлов с помощью встроенных инструментов установки Visual Studio:

  • В рамках существующего решения С# добавьте новый проект и выберите тип проекта как Other Project TypesSetup and DeploymentSetup Project (или попробуйте Мастер установки)

  • Настройте свой установщик (для этого требуется много существующих документов, если вам нужна помощь)

  • Щелкните правой кнопкой мыши проект установки в проводнике решений, выберите ViewFile Types, а затем добавьте расширение, которое вы хотите зарегистрировать вместе с программой, чтобы запустить его.

Этот метод имеет дополнительное преимущество очистки после себя, если пользователь запускает удаление для вашего приложения.

Ответ 6

Чтобы узнать о способе "Реестр Windows":

Я создаю ключи под HKEY_CURRENT_USER\Software\Classes (например, Ishmaeel сказал)

и следуйте инструкциям X-Cubed.

Пример кода выглядит так:

private void Create_abc_FileAssociation()
{
    /***********************************/
    /**** Key1: Create ".abc" entry ****/
    /***********************************/
    Microsoft.Win32.RegistryKey key1 = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software", true);

    key1.CreateSubKey("Classes");
    key1 = key1.OpenSubKey("Classes", true);

    key1.CreateSubKey(".abc");
    key1 = key1.OpenSubKey(".abc", true);
    key1.SetValue("", "DemoKeyValue"); // Set default key value

    key1.Close();

    /*******************************************************/
    /**** Key2: Create "DemoKeyValue\DefaultIcon" entry ****/
    /*******************************************************/
    Microsoft.Win32.RegistryKey key2 = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software", true);

    key2.CreateSubKey("Classes");
    key2 = key2.OpenSubKey("Classes", true);

    key2.CreateSubKey("DemoKeyValue");
    key2 = key2.OpenSubKey("DemoKeyValue", true);

    key2.CreateSubKey("DefaultIcon");
    key2 = key2.OpenSubKey("DefaultIcon", true);
    key2.SetValue("", "\"" + "(The icon path you desire)" + "\""); // Set default key value

    key2.Close();

    /**************************************************************/
    /**** Key3: Create "DemoKeyValue\shell\open\command" entry ****/
    /**************************************************************/
    Microsoft.Win32.RegistryKey key3 = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software", true);

    key3.CreateSubKey("Classes");
    key3 = key3.OpenSubKey("Classes", true);

    key3.CreateSubKey("DemoKeyValue");
    key3 = key3.OpenSubKey("DemoKeyValue", true);

    key3.CreateSubKey("shell");
    key3 = key3.OpenSubKey("shell", true);

    key3.CreateSubKey("open");
    key3 = key3.OpenSubKey("open", true);

    key3.CreateSubKey("command");
    key3 = key3.OpenSubKey("command", true);
    key3.SetValue("", "\"" + "(The application path you desire)" + "\"" + " \"%1\""); // Set default key value

    key3.Close();
}

Просто покажите вам, ребята, быструю демонстрацию, очень легко понять. Вы можете изменить эти ключевые значения, и все будет хорошо.

Ответ 7

Ассоциации файлов определены в реестре под HKEY_CLASSES_ROOT.

Вот пример VB.NET здесь, что я могу легко переносить на С#.

Ответ 8

Есть два инструмента cmd, которые были вокруг с Windows 7, которые упрощают создание простых ассоциаций файлов. Они Assoc и FType. Вот базовое объяснение каждой команды.

  • Assoc - связывает расширение файла (например, ".txt" ) с "типом файла".
  • FType - определяет исполняемый файл для запуска, когда пользователь открывает данный тип файла.

Обратите внимание, что это cmd-инструменты, а не исполняемые файлы (exe). Это означает, что их можно запустить только в CMD-окне или с помощью ShellExecute с "cmd/c -компонентом". Вы можете узнать больше о них по ссылкам или набрав "assoc/?" и "ftype/?" в командной строке cmd.

Итак, чтобы связать приложение с расширением .bob, вы можете открыть окно cmd (WindowKey + R, введите cmd, нажмите enter) и выполните следующее:

assoc .bob=BobFile
ftype BobFile=c:\temp\BobView.exe "%1"

Это намного проще, чем возиться с реестром, и, скорее всего, он будет работать в будущей версии Windows.

Объединив его, вот С# -функция для создания ассоциации файлов:

public static int setFileAssociation(string[] extensions, string fileType, string openCommandString) {
    int v = execute("cmd", "/c ftype " + fileType + "=" + openCommandString);
    foreach (string ext in extensions) {
        v = execute("cmd", "/c assoc " + ext + "=" + fileType);
        if (v != 0) return v;
    }
    return v;
}
public static int execute(string exeFilename, string arguments) {
    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.CreateNoWindow = false;
    startInfo.UseShellExecute = true;
    startInfo.FileName = exeFilename;
    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    startInfo.Arguments = arguments;
    try {
        using (Process exeProcess = Process.Start(startInfo)) {
            exeProcess.WaitForExit();
            return exeProcess.ExitCode;
        }
    } catch {
        return 1;
    }
}

Ответ 9

Ниже приведен код, который должен работать, он добавляет необходимые значения в реестр Windows. Обычно я запускаю SelfCreateAssociation ( ". Abc" ) в своем исполняемом файле. (конструктор форм или onload или onshown) Он обновит запись реестра для текущего пользователя, каждый раз, когда исполняемый файл выполняется. (полезно для отладки, если у вас есть некоторые изменения). Если вам нужна подробная информация о связанных с ним разделах реестра, ознакомьтесь с этой ссылкой MSDN.

https://msdn.microsoft.com/en-us/library/windows/desktop/dd758090(v=vs.85).aspx

Получить дополнительную информацию об общем ключе реестра ClassesRoot. См. Статью MSDN.

https://msdn.microsoft.com/en-us/library/windows/desktop/ms724475(v=vs.85).aspx

public enum KeyHiveSmall
{
    ClassesRoot,
    CurrentUser,
    LocalMachine,
}

/// <summary>
/// Create an associaten for a file extension in the windows registry
/// CreateAssociation(@"vendor.application",".tmf","Tool file",@"C:\Windows\SYSWOW64\notepad.exe",@"%SystemRoot%\SYSWOW64\notepad.exe,0");
/// </summary>
/// <param name="ProgID">e.g. vendor.application</param>
/// <param name="extension">e.g. .tmf</param>
/// <param name="description">e.g. Tool file</param>
/// <param name="application">e.g.  @"C:\Windows\SYSWOW64\notepad.exe"</param>
/// <param name="icon">@"%SystemRoot%\SYSWOW64\notepad.exe,0"</param>
/// <param name="hive">e.g. The user-specific settings have priority over the computer settings. KeyHive.LocalMachine  need admin rights</param>
public static void CreateAssociation(string ProgID, string extension, string description, string application, string icon, KeyHiveSmall hive = KeyHiveSmall.CurrentUser)
{
    RegistryKey selectedKey = null;

    switch (hive)
    {
        case KeyHiveSmall.ClassesRoot:
            Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(extension).SetValue("", ProgID);
            selectedKey = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(ProgID);
            break;

        case KeyHiveSmall.CurrentUser:
            Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\Classes\" + extension).SetValue("", ProgID);
            selectedKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\Classes\" + ProgID);
            break;

        case KeyHiveSmall.LocalMachine:
            Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"Software\Classes\" + extension).SetValue("", ProgID);
            selectedKey = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"Software\Classes\" + ProgID);
            break;
    }

    if (selectedKey != null)
    {
        if (description != null)
        {
            selectedKey.SetValue("", description);
        }
        if (icon != null)
        {
            selectedKey.CreateSubKey("DefaultIcon").SetValue("", icon, RegistryValueKind.ExpandString);
            selectedKey.CreateSubKey(@"Shell\Open").SetValue("icon", icon, RegistryValueKind.ExpandString);
        }
        if (application != null)
        {
            selectedKey.CreateSubKey(@"Shell\Open\command").SetValue("", "\"" + application + "\"" + " \"%1\"", RegistryValueKind.ExpandString);
        }
    }
    selectedKey.Flush();
    selectedKey.Close();
}

 /// <summary>
    /// Creates a association for current running executable
    /// </summary>
    /// <param name="extension">e.g. .tmf</param>
    /// <param name="hive">e.g. KeyHive.LocalMachine need admin rights</param>
    /// <param name="description">e.g. Tool file. Displayed in explorer</param>
    public static void SelfCreateAssociation(string extension, KeyHiveSmall hive = KeyHiveSmall.CurrentUser, string description = "")
    {
        string ProgID = System.Reflection.Assembly.GetExecutingAssembly().EntryPoint.DeclaringType.FullName;
        string FileLocation = System.Reflection.Assembly.GetExecutingAssembly().Location;
        CreateAssociation(ProgID, extension, description, FileLocation, FileLocation + ",0", hive);
    }