2008-09-16 4 views
45

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

+0

Это тщательно ответил в следующем потоке: http://stackoverflow.com/questions/2993118/how-to-perform-shell-icon-embedding-in-visual-studio -2010/10415947 # 10415947 – 2012-05-02 14:40:35

+0

Об этом подробно сказано в следующей статье [поток переполнения стека] (http://stackoverflow.com/questions/2993118/how-to-perform-shell-icon-embedding-in-visual-studio -2010/10415947 # 10415947). Мы использовали эту реализацию, и она отлично работает. Он также является открытым исходным кодом и интегрируется в MSBuild. – 2012-05-02 14:40:21

+2

@BlakeNiemyjski Как ваши ссылки о встраивании значков в сборки .NET, относящиеся к этому вопросу об ассоциации расширения файлов? – 2012-08-22 18:28:47

ответ

2

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

Есть пример VB.NET here, что я могу с легкостью переносить на C#.

38

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\"" 
25

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

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

7

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

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

  1. в пределах существующей C# решение, добавьте новый проект и выберите тип проекта, как Other Project Types ->Setup and Deployment ->Setup Project (или попробовать Мастер установки)

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

  3. Щелкните правой кнопкой мыши проект установки в обозревателе решений, выберите View ->File Types, а затем добавить расширение, которое вы хотите для регистрации вместе с программой для ее запуска.

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

11

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

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

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

См. Также MSDN: How to: Create File Associations For a ClickOnce Application

5

Конкретно о том, как "реестра Windows":

создать ключи под HKEY_CURRENT_USER \ Software \ Classes (как сказал Ishmaeel)

и следовать инструкциям ответили на X-кубе.

Пример кода выглядит следующим образом:

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(); 
} 

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

8

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

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; 
    } 
0

Есть два 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.

Обертывание его, вот C# функция для создания ассоциации файлов:

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; 
    } 
} 
0

ниже код является функция должна работать, она добавляет необходимые значения в реестре 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); 
    } 
Смежные вопросы