Como associar uma extensão de arquivo para o executável atual em c #

Eu gostaria de associar uma extensão de arquivo para o executável atual em c #. Dessa forma, quando o usuário clicar no arquivo depois no explorer, ele executará meu executável com o arquivo fornecido como o primeiro argumento. O ideal seria definir também o ícone das extensões de arquivo para o ícone do meu executável. Obrigado a todos.

Não parece haver uma API .Net para gerenciar diretamente as associações de arquivos, mas você pode usar as classs do Registro para ler e gravar as chaves necessárias.

Você precisará criar uma chave em HKEY_CLASSES_ROOT com o nome definido para sua extensão de arquivo (por exemplo: “.txt”). Defina o valor padrão dessa chave para um nome exclusivo para o tipo de arquivo, como “Acme.TextFile”. Em seguida, crie outra chave em HKEY_CLASSES_ROOT com o nome definido como “Acme.TextFile”. Adicione uma subchave chamada “DefaultIcon” e defina o valor padrão da chave para o arquivo que contém o ícone que você deseja usar para este tipo de arquivo. Adicione outro irmão chamado “shell”. Sob a chave “shell”, adicione uma chave para cada ação que você deseja ter disponível através do menu de contexto do Explorer, definindo o valor padrão de cada chave para o caminho do executável seguido por um espaço e “% 1” para representar o caminho para o arquivo selecionado.

Por exemplo, aqui está um arquivo de registro de amostra para criar uma associação entre os arquivos .txt e o EmEditor:

 Windows Registry Editor versão 5.00

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

 [HKEY_CLASSES_ROOT \ emeditor.txt]
 @ = "Documento de Texto"

 [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: \\ Arquivos de Programas \\ EmEditor \\ EMEDITOR.EXE \ "\"% 1 \ ""

 [HKEY_CLASSES_ROOT \ emeditor.txt \ shell \ print]

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

Além disso, se você decidir seguir o caminho do registro, lembre-se de que as associações de usuários atuais estão em HKEY_CURRENT_USER \ Software \ Classes . Pode ser melhor adicionar seu aplicativo lá em vez de classs de máquina local.

Se o seu programa for executado por usuários limitados, você não poderá modificar o CLASSES_ROOT de qualquer maneira.

Se você usar a implantação ClickOnce, tudo isso será feito para você (pelo menos no VS2008 SP1); simplesmente:

  • Propriedades do Projeto
  • Publicar
  • Opções
  • Associações de arquivos
  • (adicione o que você precisa)

(note que deve ser full-trust, alvo do .NET 3.5 e ser configurado para uso offline)

Consulte também MSDN: Como: Criar associações de arquivos para um aplicativo ClickOnce

Aqui está um exemplo completo:

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($@"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; } 

Pode haver razões específicas pelas quais você opta por não usar um pacote de instalação para o seu projeto, mas um pacote de instalação é um ótimo local para realizar facilmente as tarefas de configuração do aplicativo, como registrar extensões de arquivo, adicionar atalhos da área de trabalho etc.

Veja como criar associações de extensões de arquivos usando as ferramentas integradas do Visual Studio Install:

  1. Dentro da sua solução C # existente, adicione um novo projeto e selecione o tipo de projeto como Other Project Types -> Setup and Deployment -> Setup Project (ou tente o Assistente de Configuração)

  2. Configure seu instalador (muitos documentos existentes para isso, se precisar de ajuda)

  3. Clique com o botão direito do mouse no projeto de instalação no Solution explorer, selecione View -> File Types e adicione a extensão que você deseja registrar junto com o programa para executá-la.

Esse método tem o benefício adicional de limpar depois de si mesmo se um usuário executar a desinstalação de seu aplicativo.

Para ser específico sobre o modo “Registro do Windows”:

Eu crio chaves em HKEY_CURRENT_USER \ Software \ Classes (como Ishmaeel disse)

e siga as instruções respondidas por X-Cubed.

O código de amostra é semelhante a:

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

Basta mostrar a vocês uma demonstração rápida, muito fácil de entender. Você pode modificar esses valores-chave e tudo está pronto.

As associações de arquivos são definidas no registro em HKEY_CLASSES_ROOT.

Há um exemplo de VB.NET aqui que eu sou você pode porta facilmente para c #.

O código abaixo é uma function que deve funcionar, ele adiciona os valores necessários no registro do Windows. Normalmente eu corro SelfCreateAssociation (“. Abc”) no meu executável. (construtor de formulário ou onload ou onshown) Ele atualizará a input do registrador para o usuário atual, toda vez que o executável for executado. (bom para debugging, se você tiver algumas alterações). Se você precisar de informações detalhadas sobre as chaves de registro envolvidas, verifique este link do MSDN.

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

Para obter mais informações sobre a chave geral do Registro ClassesRoot. Veja este artigo do MSDN.

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

 public enum KeyHiveSmall { ClassesRoot, CurrentUser, LocalMachine, } ///  /// 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"); ///  /// eg vendor.application /// eg .tmf /// eg Tool file /// eg @"C:\Windows\SYSWOW64\notepad.exe" /// @"%SystemRoot%\SYSWOW64\notepad.exe,0" /// eg The user-specific settings have priority over the computer settings. KeyHive.LocalMachine need admin rights 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(); } ///  /// Creates a association for current running executable ///  /// eg .tmf /// eg KeyHive.LocalMachine need admin rights /// eg Tool file. Displayed in explorer 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); } 

Existem duas ferramentas cmd que existem desde o Windows 7, o que torna muito fácil criar associações de arquivos simples. Eles são assoc e ftype . Aqui está uma explicação básica de cada comando.

  • Assoc – associa uma extensão de arquivo (como ‘.txt’) a um “tipo de arquivo”.
  • FType – define um executável para ser executado quando o usuário abre um determinado “tipo de arquivo”.

Note que estas são ferramentas cmd e não arquivos executáveis ​​(exe). Isso significa que eles só podem ser executados em uma janela cmd ou usando ShellExecute com “cmd / c assoc”. Você pode aprender mais sobre eles nos links ou digitando “assoc /?” e “ftype /?” em um prompt de cmd.

Então, para associar um aplicativo a uma extensão .bob, você poderia abrir uma janela cmd (WindowKey + R, digitar cmd, pressionar enter) e executar o seguinte:

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

Isso é muito mais simples do que mexer com o registro e é mais provável que funcione na versão futura do Windows.

Resumindo, aqui está uma function C # para criar uma associação de arquivos:

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