2008-09-16 4 views
45

में वर्तमान निष्पादन योग्य में फ़ाइल एक्सटेंशन को कैसे संबद्ध करें मैं एक फ़ाइल एक्सटेंशन को वर्तमान निष्पादन योग्य सी # में जोड़ना चाहता हूं। इस तरह जब उपयोगकर्ता एक्सप्लोरर में बाद में फ़ाइल पर क्लिक करता है, तो यह मेरे निष्पादन योग्य को दिए गए फ़ाइल के साथ पहली तर्क के रूप में चलाएगा। आदर्श रूप से यह मेरे निष्पादन योग्य के लिए आइकन पर दिए गए फ़ाइल एक्सटेंशन के लिए आइकन भी सेट करेगा। धन्यवाद सब कुछ।सी #

+0

यह अच्छी तरह से निम्नलिखित सूत्र में जवाब दिया गया है: http://stackoverflow.com/questions/2993118/how-to-perform-shell-icon-embedding-in-visual-studio -2010/10415 9 47 # 10415 9 47 –

+0

इसका निम्नलिखित [स्टैक ओवरफ्लो थ्रेड] में पूरी तरह उत्तर दिया गया है (http://stackoverflow.com/questions/2993118/how-to-perform-shell-icon-embedding-in-visual-studio -2010/10415947 # 10415947)। हम इस कार्यान्वयन का उपयोग कर रहे हैं और यह बहुत अच्छा काम करता है। यह ओपन सोर्स भी है और एमएसबिल्ड में एकीकृत है। –

+2

@BlakeNiemyjski फ़ाइल एक्सटेंशन एसोसिएशन के बारे में इस प्रश्न के लिए प्रासंगिक .NET असेंबली में आइकन एम्बेड करने के बारे में आपके लिंक कैसे हैं? –

उत्तर

2

फ़ाइल संघों को HKEY_CLASSES_ROOT के अंतर्गत रजिस्ट्री में परिभाषित किया गया है।

एक वीबीएनईटी उदाहरण here है कि मैं आसानी से सी # पर पोर्ट कर सकता हूं।

38

फ़ाइल एसोसिएशन को सीधे प्रबंधित करने के लिए .Net API नहीं लगता है लेकिन आप रजिस्ट्री कक्षाओं को पढ़ने और लिखने के लिए रजिस्ट्री कक्षाओं का उपयोग कर सकते हैं।

आपको अपने फ़ाइल एक्सटेंशन (जैसे: ".txt") पर सेट नाम के साथ HKEY_CLASSES_ROOT के तहत एक कुंजी बनाने की आवश्यकता होगी। इस फ़ाइल के डिफ़ॉल्ट मान को अपने फ़ाइल प्रकार के लिए एक अद्वितीय नाम पर सेट करें, जैसे कि "Acme.TextFile"। फिर "Acme.TextFile" पर सेट नाम के साथ HKEY_CLASSES_ROOT के तहत एक और कुंजी बनाएं। "DefaultIcon" नामक एक उपकुंजी जोड़ें और उस फ़ाइल के लिए उस आइकन के साथ कुंजी का डिफ़ॉल्ट मान सेट करें जिसमें आप इस फ़ाइल प्रकार के लिए उपयोग करना चाहते हैं। "खोल" नामक एक और भाई जोड़ें। "खोल" कुंजी के अंतर्गत, एक्सप्लोरर संदर्भ मेनू के माध्यम से प्रत्येक क्रिया के लिए एक कुंजी जोड़ें, प्रत्येक निष्पादन योग्य के पथ पर प्रत्येक कुंजी के लिए डिफ़ॉल्ट मान को स्थान के बाद और पथ का प्रतिनिधित्व करने के लिए "% 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\"" 
+0

क्या exe के लिए कुछ तर्क पारित करने का कोई तरीका है (इस मामले में सी: \ प्रोग्राम फ़ाइलें \ EmEditor \ EMEDITOR.EXE)? – Apparao

+0

@Apparao हां, उदाहरण के रूप में प्रिंट कमांड को देखें। यह फ़ाइल नाम से पहले एक/पी पैरामीटर पास करता है। –

25

इसके अलावा, अगर आप रजिस्ट्री रास्ते जाने के लिए निर्णय लेते हैं, कि वर्तमान उपयोगकर्ता संघों के तहत कर रहे ध्यान में रखना HKEY_CURRENT_USER \ Software \ Classes। स्थानीय मशीन कक्षाओं के बजाय वहां अपना आवेदन जोड़ना बेहतर हो सकता है।

यदि आपका प्रोग्राम सीमित उपयोगकर्ताओं द्वारा चलाया जाएगा, तो आप किसी भी तरह से CLASSES_ROOT को संशोधित करने में सक्षम नहीं होंगे।

7

वहाँ अपनी परियोजना के लिए एक स्थापित पैकेज का उपयोग करने के लिए, लेकिन एक स्थापित पैकेज एक महान जगह आसानी से आवेदन विन्यास कार्य इस तरह के पंजीकरण के फ़ाइल एक्सटेंशन प्रदर्शन करना है विशिष्ट कारणों तुम क्यों नहीं चुनते हैं, जोड़ने डेस्कटॉप शॉर्टकट, आदि हो सकता है

>Setup and Deployment - ->Setup Project (या कोशिश,

  1. अपने मौजूदा सी # समाधान के भीतर Other Project Types के रूप में एक नई परियोजना का चयन करें और परियोजना प्रकार जोड़: यहाँ निर्मित दृश्य स्टूडियो स्थापित करें उपकरण का उपयोग कर फाइल एक्सटेंशन संघ बनाने का तरीका बताया सेटअप विज़ार्ड)

  2. कॉन्फ़िगर अपने संस्थापक (इस के लिए मौजूदा डॉक्स के बहुत सारे आप मदद की जरूरत है)

  3. राइट-क्लिक करें समाधान एक्सप्लोरर में सेटअप परियोजना का चयन View, -,>File Types और फिर विस्तार है जो आप चाहते हैं जोड़ने इसे चलाने के लिए कार्यक्रम के साथ पंजीकरण करने के लिए।

यदि कोई उपयोगकर्ता आपके एप्लिकेशन के लिए अनइंस्टॉल चलाता है तो इस विधि में स्वयं के बाद सफाई का अतिरिक्त लाभ होता है।

11

यदि आप क्लिकऑन परिनियोजन का उपयोग करते हैं, तो यह सब आपके लिए संभाला जाता है (कम से कम, वीएस -2008 एसपी 1 में); बस:

  • प्रोजेक्ट गुण
  • प्रकाशित
  • विकल्प
  • फ़ाइल Associatons
  • (जोड़ने जो कुछ भी आप की जरूरत है)

(ध्यान दें कि यह पूर्ण विश्वास, लक्ष्य होना चाहिए। नेट 3.5, और ऑफलाइन उपयोग के लिए सेट किया गया है)

एमएसडीएन भी देखें: How to: Create File Associations For a ClickOnce Application

+1

मेरे पास वीएस -2008 प्रोफेशनल, एसपी 1 है और मुझे यह विकल्प नहीं दिख रहा है। मेरा कुछ छूट रहा है। – Jerry

5

"Windows रजिस्ट्री" जिस तरह के बारे में विशिष्ट होने के लिए:

मैं HKEY_CURRENT_USER \ Software \ Classes तहत कुंजी बनाने के (जैसे Ishmaeel कहा)

और शिक्षा एक्स-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(); 
} 

बस तुम लोग एक त्वरित प्रदर्शन दिखाने के लिए, समझने में आसान। आप उन महत्वपूर्ण मूल्यों को संशोधित कर सकते हैं और सब कुछ ठीक है।

+1

आइकन का उपयोग करने के लिए खोल को सूचित करने के लिए आवश्यक कोड जोड़ने के लिए मत भूलना। 'SHChangeNotify (0x8000000, 0, 0, 0);' – randomsolutions

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 उपकरण है कि चारों ओर विंडोज 7 जो यह बहुत आसान सरल फ़ाइलों के समूह बनाने के लिए बनाने के बाद से किया गया है। वे assoc और ftype हैं। यहां प्रत्येक कमांड का मूल स्पष्टीकरण दिया गया है।

  • Assoc - फ़ाइल एक्सटेंशन (जैसे '.txt') को "फ़ाइल प्रकार" के साथ जोड़ता है।
  • FType - उपयोगकर्ता द्वारा दिए गए "फ़ाइल प्रकार" को खोलने पर निष्पादन योग्य को परिभाषित करता है।

ध्यान दें कि ये cmd उपकरण हैं और निष्पादन योग्य फ़ाइलें (exe) नहीं हैं। इसका मतलब है कि वे केवल एक cmd विंडो में चलाए जा सकते हैं, या "cmd/c assoc" के साथ ShellExecute का उपयोग करके। आप लिंक पर या "assoc /?" टाइप करके उनके बारे में अधिक जान सकते हैं और "ftype /?" एक cmd प्रॉम्प्ट पर।

तो एक .bob विस्तार के साथ एक आवेदन पत्र संबद्ध करने के लिए, आप एक cmd विंडो (WindowKey + आर, प्रकार cmd, प्रेस दर्ज करें) खोल सके और निम्नलिखित चलाएँ:

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

यह खिलवाड़ तुलना में बहुत सरल है रजिस्ट्री के साथ और भविष्य के विंडोज संस्करण में काम करने की अधिक संभावना है।

यह रैपिंग ऊपर, यहाँ एक फ़ाइल संघ बनाने के लिए एक सी # समारोह है:

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

नीचे कोड एक समारोह काम करना चाहिए है, यह विंडोज़ रजिस्ट्री में आवश्यक मान कहते हैं। आमतौर पर मैं अपने निष्पादन योग्य में SelfCreateAssociation ("। Abc") चलाता हूं।(फॉर्म कन्स्ट्रक्टर या ऑनलोड या ऑनशॉउन) यह वर्तमान उपयोगकर्ता के लिए रजिस्टरी एंट्री अपडेट करेगा, हर बार निष्पादन योग्य निष्पादित किया जाएगा। (अगर आपके पास कुछ बदलाव हैं तो डीबगिंग के लिए अच्छा)। यदि आपको शामिल रजिस्ट्री कुंजियों के बारे में विस्तृत जानकारी की आवश्यकता है तो यह एमएसडीएन लिंक देखें।

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

सामान्य ClassesRoot रजिस्ट्री कुंजी के बारे में और अधिक जानकारी प्राप्त करने के लिए। यह एमएसडीएन आलेख देखें।

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

कोई स्पष्टीकरण के साथ कोड का एक बड़ा ब्लॉक छोड़ना भविष्य के पाठकों के लिए शायद ही उपयोगी है। कृपया इस कोड के बारे में कुछ स्पष्टीकरण दें और जोड़ें। – Nisarg