51

.Net (C# または VB: don't care) では、実際に存在するファイルのファイル パス文字列、FileInfo 構造体、または FileSystemInfo 構造体が与えられた場合、シェル (エクスプローラー) が使用するアイコンをどのように判断できますか?ファイル?

現在、これを何にも使用する予定はありませんが、この質問を見たときにその方法に興味があり、SO でここにアーカイブしておくと便利だと思いました。

4

9 に答える 9

63
Imports System.Drawing
Module Module1

    Sub Main()    
        Dim filePath As String =  "C:\myfile.exe"  
        Dim TheIcon As Icon = IconFromFilePath(filePath)  

        If TheIcon IsNot Nothing Then    
            ''#Save it to disk, or do whatever you want with it.
            Using stream As New System.IO.FileStream("c:\myfile.ico", IO.FileMode.CreateNew)
                TheIcon.Save(stream)          
            End Using
        End If
    End Sub

    Public Function IconFromFilePath(filePath As String) As Icon
        Dim result As Icon = Nothing
        Try
            result = Icon.ExtractAssociatedIcon(filePath)
        Catch ''# swallow and return nothing. You could supply a default Icon here as well
        End Try
        Return result
    End Function
End Module
于 2009-01-20T17:40:42.707 に答える
17

レジストリを使用するように言っている人は無視してください。レジストリは API ではありません。必要な API は、SHGFI_ICON を使用した SHGetFileInfo です。ここで P/Invoke 署名を取得できます。

http://www.pinvoke.net/default.aspx/shell32.SHGetFileInfo

于 2009-01-20T18:24:03.947 に答える
10

ステファンの答えのC#バージョンにすぎません。

using System.Drawing;

class Class1
{
    public static void Main()
    {
        var filePath =  @"C:\myfile.exe";
        var theIcon = IconFromFilePath(filePath);

        if (theIcon != null)
        {
            // Save it to disk, or do whatever you want with it.
            using (var stream = new System.IO.FileStream(@"c:\myfile.ico", System.IO.FileMode.CreateNew))
            {
                theIcon.Save(stream);
            }
        }
    }

    public static Icon IconFromFilePath(string filePath)
    {
        var result = (Icon)null;

        try
        {
            result = Icon.ExtractAssociatedIcon(filePath);
        }
        catch (System.Exception)
        {
            // swallow and return nothing. You could supply a default Icon here as well
        }

        return result;
    }
}
于 2013-10-18T08:08:57.987 に答える
1

特定の拡張機能のアイコンのみに関心があり、一時ファイルを作成してもかまわない場合は、ここに表示されている例に従うことができます

C# コード:

    public Icon LoadIconFromExtension(string extension)
    {
        string path = string.Format("dummy{0}", extension);
        using (File.Create(path)) { }
        Icon icon = Icon.ExtractAssociatedIcon(path);
        File.Delete(path);
        return icon;
    }
于 2012-06-29T06:48:51.857 に答える
1

レジストリ アプローチの問題は、アイコン インデックス ID を明示的に取得していないことです。場合によっては (常にではないにしても)、アプリケーション開発者がアイコンのスロットに名前を付けるために使用したエイリアスであるアイコン ResourceID を取得します。

したがって、レジストリ メソッドは、すべての開発者が暗黙的なアイコン インデックス ID (ゼロ ベース、絶対、決定論的) と同じ ResourceID を使用することを意味します。

レジストリの場所をスキャンすると、多くの負の数が表示され、場合によってはテキスト参照も表示されます。つまり、アイコン インデックス ID ではありません。OSに作業を任せるので、暗黙的な方法の方が良いようです。

現在、この新しい方法をテストしているだけですが、理にかなっていて、うまくいけばこの問題を解決します。

于 2011-07-27T19:49:50.027 に答える
0

このリンクにはいくつかの情報があるようです。これには多くのレジストリのトラバースが含まれますが、実行可能のようです。例は C++ です

于 2009-01-20T17:42:17.650 に答える
0
  • 拡張子を決定する
  • レジストリで、に移動し"HKCR\.{extension}"、デフォルト値を読み取ります (それを と呼びましょうfiletype)
  • "HKCR\{filetype}\DefaultIcon"、デフォルト値を読み取ります。これは、アイコン ファイル (または、アイコン リソースが埋め込まれた .exe などのアイコン コンテナー ファイル) へのパスです。
  • 必要に応じて、上記のファイルからアイコン リソースを抽出するお好みの方法を使用します。

コメントから編集/上に移動:

アイコンがコンテナ ファイル内にある場合 (これは非常に一般的です)、次のようにパスの後にカウンターが表示されます"foo.exe,3"。これは、使用可能なアイコンのアイコン番号 4 (インデックスはゼロベース) であることを意味します。",0" の値は暗黙的 (およびオプション) です。カウンターが 0 または欠落している場合、最初に使用可能なアイコンがシェルによって使用されます。

于 2009-01-20T17:48:08.120 に答える