it-swarm-tr.com

Bir dosya uzantısını C # 'da bulunan geçerli dosya ile ilişkilendirme

Bir dosya uzantısını C # ..__ dosyasındaki geçerli çalıştırılabilir dosyayla ilişkilendirmek istiyorum: Bu durumda kullanıcı dosyayı daha sonra Explorer'da tıklattığında, ilk dosya argümanı olarak verilen dosyayla çalıştırılabilir dosyamı çalıştırır. Ayrıca, dosya uzantıları için verilen simgeyi çalıştırılabilir dosyamın simgesine ayarlar.

51
Chris

Dosya ilişkilerini doğrudan yönetmek için bir .NET API görünmüyor, ancak gereken anahtarları okumak ve yazmak için Kayıt Defteri sınıflarını kullanabilirsiniz.

HKEY_CLASSES_ROOT altında bir dosya yaratmanız gerekir (örneğin: ".txt"). Bu anahtarın varsayılan değerini, "Acme.TextFile" gibi dosya türünüz için benzersiz bir ad olarak ayarlayın. Ardından "Acme.TextFile" olarak ayarlanan adla HKEY_CLASSES_ROOT altında başka bir anahtar oluşturun. "DefaultIcon" adlı bir alt anahtar ekleyin ve anahtarın varsayılan değerini, bu dosya türü için kullanmak istediğiniz simgeyi içeren dosyaya ayarlayın. "Shell" adında başka bir kardeş ekleyin. "Kabuk" tuşunun altına, Explorer içerik menüsü üzerinden kullanmak istediğiniz her bir işlem için bir tuş ekleyin, her tuş için varsayılan değeri çalıştırılabilir yolunuzun yoluna getirin, ardından boşluğu ve "% 1" yolunu gösterin. seçilen dosyaya.

Örneğin, .txt dosyaları ve EmEditor arasında bir ilişki oluşturmak için örnek bir kayıt defteri dosyası:

 Windows Kayıt Defteri Düzenleyicisi Sürüm 5.00 

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

 [HKEY_CLASSES_ROOT\emeditor.txt] 
 @ Doküman" 

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

 [hkey_classes_root\emeditor.txt\Shell] 
.__ [hkey_classes_root\emeditor.txt\Shell\açık] 
.__ [hkey_classes_root\emeditor.txt\Shell\açık\komutu] .__ @ = "\" Cı.:..\\ Program Dosyaları \\ EmEditor \\ EMEDITOR.EXE\"\"% 1\"" 

 [HKEY_CLASSES_ROOT\emeditor.txt\Shell\print] 

 [HKEY_CLASSES_ROOT\emeditor.txt\Shell\print\command] 
 @ = "\" C: \\ Program Dosyaları \\ EmEditor \\ EMEDITOR.EXE\"/ p \"% 1\"" 
40
X-Cubed

Ayrıca, kayıt defteri yoluna gitmeye karar verirseniz, geçerli kullanıcı ilişkilerinin HKEY_CURRENT_USER\Software\Classes altında olduğunu unutmayın. Uygulamanızı yerel makine sınıfları yerine oraya eklemek daha iyi olabilir.

Programınız sınırlı kullanıcılar tarafından çalıştırılacaksa, yine de CLASSES_ROOT'u değiştiremezsiniz.

25
Ishmaeel

ClickOnce dağıtımını kullanıyorsanız, bunların tümü sizin için kullanılır (en azından VS2008 SP1'de); basitçe:

  • Proje Özellikleri
  • Yayınla
  • Seçenekler
  • Dosya Birliği
  • (ihtiyacınız olanı ekleyin)

(tam güvende olması gerektiğini, .NET 3.5'i hedeflemesi ve çevrimdışı kullanım için ayarlanması gerektiğini unutmayın)

Ayrıca bakınız MSDN: Nasıl Yapılır: ClickOnce Uygulaması İçin Dosya İlişkileri Oluşturma

11
Marc Gravell

İşte tam bir örnek:

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;
    }
9
Kirill Osenkov

Projeniz için bir yükleme paketi kullanmamayı seçmenizin belirli nedenleri olabilir, ancak yükleme paketi dosya uzantılarını kaydetme, masaüstü kısayolları ekleme vb. Gibi uygulama yapılandırma görevlerini kolayca gerçekleştirmek için harika bir yerdir.

Yerleşik Visual Studio Install araçlarını kullanarak dosya uzantısı ilişkilendirmesini nasıl oluşturacağınız:

  1. Mevcut C # çözümünüzde yeni bir proje ekleyin ve proje türünü Other Project Types -> Setup and Deployment -> Setup Project olarak seçin (veya Kurulum Sihirbazı'nı deneyin).

  2. Yükleyicinizi yapılandırın (yardıma ihtiyacınız olursa bunun için mevcut çok sayıda doküman var)

  3. Solution Explorer'da kurulum projesine sağ tıklayın, View -> File Types seçeneğini seçin ve ardından çalıştırmak istediğiniz programla birlikte kaydetmek istediğiniz uzantıyı ekleyin.

Bir kullanıcı uygulamanız için kaldırma işlemini çalıştırdığında, bu yöntemin kendisinden sonra temizlik yapmasının yararı vardır.

7
Paul J

"Windows Kayıt Defteri" yolu hakkında net olmak için:

HKEY_CURRENT_USER\Software\Classes altında anahtarlar oluşturuyorum

ve X-Cubed tarafından verilen talimatı izleyin.

Örnek kod şöyle görünür:

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

Size kısa bir demo gösterelim, anlaşılması çok kolay. Bu anahtar değerleri değiştirebilir ve her şey yolunda gitmek iyidir.

5
Strong

Dosya ilişkileri kayıt defterinde HKEY_CLASSES_ROOT altında tanımlanmıştır.

Bir VB.NET örneği var here Ben kolayca C # 'ya taşıyabileceğimi.

2
Steve Morgan

Aşağıdaki kod çalışması gereken bir fonksiyondur, Windows kayıt defterinde gerekli değerleri ekler. Genellikle SelfCreateAssociation (". Abc") dosyasını çalıştırılabilir dosyamda çalıştırıyorum. (form oluşturucu veya yük altında veya üstünde gösteriliyor) Yürütülebilir her çalıştırmada geçerli kullanıcı için kayıt kaydını günceller. (bazı değişiklikleriniz varsa hata ayıklama için iyi) .Aşağıdaki kayıt defteri anahtarları hakkında ayrıntılı bilgiye ihtiyacınız varsa, bu MSDN bağlantısını inceleyin.

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

Genel ClassesRoot kayıt defteri anahtarı hakkında daha fazla bilgi edinmek için. Bu MSDN makalesine bakın.

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);
    }
2
Carsten R.

Windows 7'den bu yana, basit dosya ilişkilendirmeleri oluşturmayı çok kolaylaştıran iki cmd aracı var. Bunlar assoc ve ftype 'dır. İşte her komutun temel bir açıklaması.

  • Assoc - bir dosya uzantısını ('.txt' gibi) "dosya türü" ile ilişkilendirir.
  • FType -, kullanıcı verilen bir "dosya türü" açıldığında çalıştırılacak bir yürütülebilir dosya tanımlar.

Bunların cmd araçları olduğunu ve çalıştırılabilir dosyalar olmadığını (exe) unutmayın. Bu, yalnızca bir cmd penceresinde veya "cmd/c assoc" ile ShellExecute kullanarak çalıştırılabilecekleri anlamına gelir. Linkler hakkında veya "assoc /?" Yazarak onlar hakkında daha fazla bilgi edinebilirsiniz. ve "ftype /?" bir cmd isteminde. 

Bir uygulamayı bir .bob uzantısıyla ilişkilendirmek için bir cmd penceresi açabilirsiniz (WindowKey + R, cmd yazın, enter tuşuna basın) ve aşağıdakileri çalıştırın:

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

Bu, kayıt defterine bulaşmaktan çok daha kolaydır ve gelecekteki Windows sürümlerinde çalışması daha olasıdır. 

Tamamladıktan sonra, bir dosya ilişkilendirmesi oluşturmak için bir C # işlevi:

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
Mike