Znajdowanie domyślnej aplikacji do otwierania określonego typu pliku w systemie Windows

Rozwijam aplikację skierowaną do. NET Framework 2.0 przy użyciu C#, dla którego muszę być w stanie znaleźć domyślną aplikację, która jest używana do otwierania określonego typu pliku.

Wiem, że na przykład, jeśli chcesz otworzyć plik za pomocą tej aplikacji, możesz użyć czegoś takiego jak:

System.Diagnostics.Process.Start( "C:\...\...\myfile.html" );

Aby otworzyć dokument HTML w domyślnej przeglądarce lub

System.Diagnostics.Process.Start( "C:\...\...\myfile.txt" );

Aby otworzyć plik tekstowy w domyślnym edytorze tekstu.

Jednakże, chcę być w stanie zrobić to otwórz pliki, które niekoniecznie mają .rozszerzenie txt (na przykład), w domyślnym edytorze tekstu, więc muszę być w stanie znaleźć domyślną aplikację do otwierania .pliki txt , które pozwolą mi wywołać je bezpośrednio.

Zgaduję, że jest jakieś API Win32, które będę musiał P / wywołać, aby to zrobić, jednak szybkie spojrzenie zarówno z Google, jak i MSDN nie ujawniło niczego interesującego; znalazłem bardzo dużą liczbę zupełnie nieistotnych stron, ale niczego, czego szukam.

Author: Robert Harvey, 2008-10-02

6 answers

Możesz sprawdzić w sekcji rejestru HKEY_CLASSES_ROOT szczegóły rozszerzenia i akcji. Dokumentacja dla tego jest na MSDN . Alternatywnie możesz użyć interfejsu IQueryAssociations.

 17
Author: curtisk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-05 16:51:35

Wszystkie aktualne odpowiedzi są niewiarygodne. Rejestr jest szczegółem implementacji i rzeczywiście taki kod jest uszkodzony na moim komputerze z systemem Windows 8.1. Poprawnym sposobem jest użycie API Win32, w szczególności AssocQueryString :

using System.Runtime.InteropServices;

[DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern uint AssocQueryString(
    AssocF flags, 
    AssocStr str,  
    string pszAssoc, 
    string pszExtra, 
    [Out] StringBuilder pszOut, 
    ref uint pcchOut
); 

[Flags]
public enum AssocF
{
    None = 0,
    Init_NoRemapCLSID = 0x1,
    Init_ByExeName = 0x2,
    Open_ByExeName = 0x2,
    Init_DefaultToStar = 0x4,
    Init_DefaultToFolder = 0x8,
    NoUserSettings = 0x10,
    NoTruncate = 0x20,
    Verify = 0x40,
    RemapRunDll = 0x80,
    NoFixUps = 0x100,
    IgnoreBaseClass = 0x200,
    Init_IgnoreUnknown = 0x400,
    Init_Fixed_ProgId = 0x800,
    Is_Protocol = 0x1000,
    Init_For_File = 0x2000
}

public enum AssocStr
{
    Command = 1,
    Executable,
    FriendlyDocName,
    FriendlyAppName,
    NoOpen,
    ShellNewValue,
    DDECommand,
    DDEIfExec,
    DDEApplication,
    DDETopic,
    InfoTip,
    QuickTip,
    TileInfo,
    ContentType,
    DefaultIcon,
    ShellExtension,
    DropTarget,
    DelegateExecute,
    Supported_Uri_Protocols,
    ProgID,
    AppID,
    AppPublisher,
    AppIconReference,
    Max
}

Odpowiednia dokumentacja:

Przykładowe użycie:

static string AssocQueryString(AssocStr association, string extension)
{
    const int S_OK = 0;
    const int S_FALSE = 1;

    uint length = 0;
    uint ret = AssocQueryString(AssocF.None, association, extension, null, null, ref length);
    if (ret != S_FALSE)
    {
        throw new InvalidOperationException("Could not determine associated string");
    }

    var sb = new StringBuilder((int)length); // (length-1) will probably work too as the marshaller adds null termination
    ret = AssocQueryString(AssocF.None, association, extension, null, sb, ref length);
    if (ret != S_OK)
    {
        throw new InvalidOperationException("Could not determine associated string"); 
    }

    return sb.ToString();
}
 58
Author: Ohad Schneider,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-05 09:25:59

Doh! Oczywiście.

HKEY_CLASSES_ROOT\.txt

Zawiera odniesienie do

HKEY_CLASSES_ROOT\txtfile

Który zawiera podklucz

HKEY_CLASSES_ROOT\txtfile\shell\open\command

Które odwołują się do Notatnika.

Sortowane, Wielkie dzięki!

Bart

 9
Author: Bart Read,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-02 13:52:05

Oto wpis na blogu o tym temacie. próbki kodu są w VB.net, ale powinno być łatwo je przenieść do C#.

 5
Author: xsl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-02 13:48:23

Możesz po prostu odpytywać rejestr. Najpierw pobierz domyślny wpis w HKEY_CLASSES_ROOT\.ext

To da Ci nazwę klasy. Na przykład .txt ma domyślną wartość txtfile

Następnie otwórz HKEY_CLASSES_ROOT\txtfile \ Shell \ Open \ Command

To da ci domyślne polecenie.

 3
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-02 13:50:48

Późna odpowiedź, ale istnieje dobry pakiet NUGET, który obsługuje Asocjacje plików: Asocjacja Plików

Link NuGet File Association

Użycie jest proste, na przykład dodanie wszystkich dozwolonych rozszerzeń plików do menu kontekstowego:

private void OnMenuSourceFileOpening(object sender, ...)
{   // open a context menu with the associated files + ".txt" files
    if (File.Exists(this.SelectedFileName))
    {
        string fileExt = Path.GetExtension(this.SelectedFileNames);
        string[] allowedExtensions = new string[] { fileExt, ".txt" };
        var fileAssociations = allowedExtensions
            .Select(ext => new FileAssociationInfo(ext));
        var progInfos = fileAssociations
            .Select(fileAssoc => new ProgramAssociationInfo (fileAssoc.ProgID));
        var toolstripItems = myProgInfos
            .Select(proginfo => new ToolStripLabel (proginfo.Description) { Tag = proginfo });
        // add also the prog info as Tag, for easy access
        //  when the toolstrip item is selected
        // of course this can also be done in one long linq statement

        // fill the context menu:
        this.contextMenu1.Items.Clear();
        this.contextMenuOpenSourceFile.Items.AddRange (toolstripItems.ToArray());
    }
}
 2
Author: Harald Coppoolse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-16 09:35:14