Come associare un’estensione di file all’eseguibile corrente in C #

Mi piacerebbe associare un’estensione di file all’eseguibile corrente in C #. In questo modo, quando l’utente fa clic sul file in seguito in explorer, eseguirà il mio eseguibile con il file dato come primo argomento. Idealmente avrebbe anche impostato l’icona per le estensioni di file fornite all’icona per il mio eseguibile. Ringrazia tutti.

Non sembra essere un’API .Net per la gestione diretta delle associazioni di file, ma è ansible utilizzare le classi del Registro di sistema per leggere e scrivere le chiavi necessarie.

Dovrai creare una chiave in HKEY_CLASSES_ROOT con il nome impostato sull’estensione del file (ad esempio: “.txt”). Imposta il valore predefinito di questa chiave su un nome univoco per il tuo tipo di file, come “Acme.TextFile”. Quindi creare un’altra chiave in HKEY_CLASSES_ROOT con il nome impostato su “Acme.TextFile”. Aggiungi una sottochiave chiamata “DefaultIcon” e imposta il valore predefinito della chiave sul file contenente l’icona che desideri utilizzare per questo tipo di file. Aggiungi un altro fratello chiamato “shell”. Sotto la chiave “shell”, aggiungi una chiave per ogni azione che desideri avere disponibile tramite il menu di scelta rapida di Explorer, impostando il valore predefinito per ogni chiave sul percorso del tuo eseguibile seguito da uno spazio e “% 1” per rappresentare il percorso al file selezionato.

Ad esempio, ecco un file di registro di esempio per creare un’associazione tra i file .txt e EmEditor:

 Editor del Registro di sistema di Windows versione 5.00

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

 [HKEY_CLASSES_ROOT \ emeditor.txt]
 @ = "Documento di testo"

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

 [\ Emeditor.txt \ shell HKEY_CLASSES_ROOT]

 [HKEY_CLASSES_ROOT \ emeditor.txt \ shell \ open]

 [\ Emeditor.txt \ shell \ open \ command HKEY_CLASSES_ROOT]
 @ = "\" C: \\ Programmi \ EmEditor \\ EMEDITOR.EXE \ "\"% 1 \ ""

 [\ Emeditor.txt \ shell \ stampa HKEY_CLASSES_ROOT]

 [\ Emeditor.txt \ shell \ stampa \ command HKEY_CLASSES_ROOT]
 @ = "\" C: \\ Programmi \ EmEditor \\ EMEDITOR.EXE \ "/ p \"% 1 \ ""

Inoltre, se si decide di utilizzare il registro, tenere presente che le associazioni utente correnti sono in HKEY_CURRENT_USER \ Software \ Classes . Potrebbe essere meglio aggiungere la tua applicazione al posto delle classi di macchine locali.

Se il tuo programma verrà eseguito da utenti limitati, non potrai comunque modificare CLASSES_ROOT.

Se si utilizza la distribuzione ClickOnce, tutto questo viene gestito per l’utente (almeno in VS2008 SP1); semplicemente:

  • Proprietà del progetto
  • Pubblicare
  • Opzioni
  • File associati
  • (aggiungi tutto ciò che ti serve)

(nota che deve essere full-trust, target .NET 3.5 ed essere impostato per l’utilizzo offline)

Vedere anche MSDN: Procedura: creare associazioni di file per un’applicazione ClickOnce

Ecco un esempio 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([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; } 

Potrebbero esserci motivi specifici per cui scegli di non utilizzare un pacchetto di installazione per il tuo progetto, ma un pacchetto di installazione è un ottimo posto per eseguire facilmente attività di configurazione dell’applicazione come la registrazione delle estensioni di file, l’aggiunta di scorciatoie sul desktop, ecc.

Ecco come creare un’associazione di estensione file utilizzando gli strumenti di installazione di Visual Studio incorporati:

  1. All’interno della soluzione C # esistente, aggiungi un nuovo progetto e seleziona il tipo di progetto come Other Project Types -> Setup and Deployment -> Setup Project (o prova l’installazione guidata)

  2. Configura il tuo programma di installazione (un sacco di documenti esistenti per questo se hai bisogno di aiuto)

  3. Fare clic con il tasto destro del mouse sul progetto di installazione in Esplora soluzioni, selezionare View -> File Types , quindi aggiungere l’estensione che si desidera registrare insieme al programma per eseguirla.

Questo metodo ha il vantaggio aggiuntivo di ripulire se stesso se un utente esegue la disinstallazione per l’applicazione.

Per essere specifici sul modo “Registro di Windows”:

Creo le chiavi sotto HKEY_CURRENT_USER \ Software \ Classes (come ha detto Ishmaeel)

e segui le istruzioni fornite da X-Cubed.

Il codice di esempio ha il seguente aspetto:

 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 mostrarti una demo veloce, molto facile da capire. È ansible modificare quei valori chiave e tutto è a posto.

Le associazioni di file sono definite nel registro in HKEY_CLASSES_ROOT.

C’è un esempio VB.NET qui che io sono in grado di effettuare facilmente il porting su C #.

Il codice seguente è una funzione che dovrebbe funzionare, aggiunge i valori richiesti nel registro di Windows. Di solito eseguo SelfCreateAssociation (“. Abc”) nel mio eseguibile. (costruttore di moduli o onload o onshown) Aggiorna la voce di registro per l’utente corrente, ogni volta che viene eseguito l’eseguibile. (buono per il debug, se si dispone di alcune modifiche). Se hai bisogno di informazioni dettagliate sulle chiavi di registro in questione, controlla questo link MSDN.

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

Per ottenere ulteriori informazioni sulla chiave di registro ClassesRoot generale. Vedi questo articolo MSDN.

https://msdn.microsoft.com/en-us/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); } 

Ci sono due strumenti di cmd che sono stati in giro da Windows 7 che rendono molto facile creare semplici associazioni di file. Sono soci e ftype . Ecco una spiegazione di base di ciascun comando.

  • Assoc – associa un’estensione di file (come ‘.txt’) con un “tipo di file”.
  • FType : definisce un eseguibile da eseguire quando l’utente apre un determinato “tipo di file”.

Si noti che questi sono strumenti cmd e non file eseguibili (exe). Ciò significa che possono essere eseguiti solo in una finestra di cmd o utilizzando ShellExecute con “cmd / c assoc.” Puoi saperne di più su di loro ai link o digitando “assoc /?” e “ftype /?” al prompt di cmd.

Quindi, per associare un’applicazione con estensione .bob, puoi aprire una finestra di cmd (WindowKey + R, digitare cmd, premere invio) ed eseguire quanto segue:

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

Questo è molto più semplice che fare casino con il registro ed è più probabile che funzioni nella futura versione di Windows.

Avvolgendolo, ecco una funzione C # per creare un’associazione di file:

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