Bedarf ein funktionierendes Beispiel für die Extractasociatedicon -Funktion von Shell32 in .NET in .NET

StackOverflow https://stackoverflow.com/questions/1988393

  •  22-09-2019
  •  | 
  •  

Frage

Ich brauche ein funktionierendes Beispiel für die Extraktasoziatikfunktion in Shell32.dll. Ich kann es nicht zum Laufen bringen und ich habe keine Ideen mehr. Ich brauche einen weiteren Blick auf den folgenden Code. Wenn das Formular geladen wird, sollte sein Symbol auf das Visual Studio -Symbol eingestellt werden, aber alles, was ich bekomme, ist das Standardsystemsymbol.

Imports System.Runtime.InteropServices

Public Class Form1

    Public Function ExtractIcon(ByVal path As String, ByVal handle As IntPtr) As Icon
        Dim oResult As Icon
        Dim hIcon As IntPtr
        Dim iIndex As Integer
        Dim oPath As New System.Text.StringBuilder(260, 260)

        oPath.Append(path)

        hIcon = ExtractAssociatedIcon(handle, oPath, iIndex)

        'hIcon = ExtractAssociatedIcon(handle, path, iIndex)

        Dim oIcon As Icon = Icon.FromHandle(hIcon)

        oResult = DirectCast(oIcon.Clone, Icon)

        DestroyIcon(hIcon)

        Return oResult
    End Function

    Public Declare Auto Function ExtractAssociatedIcon Lib "shell32" ( _
        ByVal hInst As IntPtr, _
        <MarshalAs(UnmanagedType.LPStr)> ByVal lpIconPath As System.Text.StringBuilder, _
        ByRef lpiIcon As Integer) As IntPtr

    'Public Declare Auto Function ExtractAssociatedIcon Lib "shell32" ( _
    '    ByVal hInst As IntPtr, _
    '    <MarshalAs(UnmanagedType.LPStr)> ByVal lpIconPath As String, _
    '    ByRef lpiIcon As Integer) As IntPtr

    Friend Declare Auto Function DestroyIcon Lib "user32" (<[In]()> ByVal hIcon As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        'ExtractAssociatedIcon uses ExtractAssociatedIcon that is in Shell32.dll.
        'This works, so why doesn't mine? What am I missing?
        'Me.Icon = System.Drawing.Icon.ExtractAssociatedIcon("C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe")

        Me.Icon = ExtractIcon("C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe", Me.Handle)

    End Sub

End Class

Korrigiert

<MarshalAs(UnmanagedType.LPStr)> war das Problem. Es hätte sein sollen LPTStr, nicht LPStr.

War es hilfreich?

Lösung

Das Griff ist definitiv falsch, das erste Argument für EAI ist ein Modulgriff, kein Symbolgriff. Das hat gut funktioniert:

Imports System.Runtime.InteropServices
Imports System.ComponentModel
...
  Public Shared Function ExtractIcon(ByVal path As String, Optional ByVal index As Integer = 0) As Icon
    Dim handle As IntPtr = ExtractAssociatedIcon(IntPtr.Zero, path, index)
    If handle = IntPtr.Zero Then Throw New Win32Exception(Marshal.GetLastWin32Error())
    Dim retval As Icon = Nothing
    using temp As Icon = Icon.FromHandle(handle)
      retval = CType(temp.Clone(), Icon)
      DestroyIcon(handle)
    end using
    Return retval      
  End Function

  Private Declare Auto Function ExtractAssociatedIcon Lib "shell32" ( _
      ByVal hInst As IntPtr, ByVal path As String, ByRef index As Integer) As IntPtr
  Private Declare Auto Function DestroyIcon Lib "user32" (ByVal hIcon As IntPtr) As Boolean

Keine Notwendigkeit für StringBuilder, wenn das Modulgriff null ist. Verwenden Sie diesen Code nicht, wenn Sie nicht das "Index" -Argument haben. Icon.extractAssocationicon funktioniert ebenso gut.

Andere Tipps

Warum nicht einfach den .NET Native verwenden? Icon.ExtractAssociatedIcon Methode, die das Gleiche zu tun scheint?

Me.Icon = Icon.ExtractAssociatedIcon( _
    "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe")

PS: Ich habe Ihren Code mit dem gleichen, falschen Ergebnis ausprobiert, das Sie beschrieben haben. Das obige Code -Snippet scheint jedoch zu funktionieren.

Probieren Sie die native .NET -Methode aus, die Stakx erwähnt - ich habe ein Glück damit, die ICO -Datei zu speichern (wenn Sie als ein anderes Format speichern, beispielsweise Bitmap, funktioniert sie jedoch normalerweise)

Für ein Pinvoke so sollte so etwas funktionieren: (Vorbehalt, nicht getestet) verwiesen: http://social.msdn.microsoft.com/forums/en-us/csharpgeneral/thread/ecb6137c-8bda-4468-b5e0-359caeb202b1

[DllImport("Shell32.dll")]
private static extern int SHGetFileInfo( string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbfileInfo, SHGFI uFlags );

[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
    public SHFILEINFO(bool b)
    {
        hIcon = IntPtr.Zero; iIcon = 0; dwAttributes = 0; szDisplayName = ""; szTypeName = "";
    }
    public IntPtr hIcon;
    public int iIcon;
    public uint dwAttributes;

    [MarshalAs(UnmanagedType.LPStr, SizeConst = 260)]
    public string szDisplayName;

    [MarshalAs(UnmanagedType.LPStr, SizeConst = 80)]
    public string szTypeName;
};

private ExtractIcon()
{
}

private enum SHGFI
{
    SmallIcon = 0x00000001,
    LargeIcon = 0x00000000,
    Icon = 0x00000100,
    DisplayName = 0x00000200,
    Typename = 0x00000400,
    SysIconIndex = 0x00004000,
    UseFileAttributes = 0x00000010
}

public static Icon GetIcon(string strPath, bool bSmall)
{
    SHFILEINFO info = new SHFILEINFO(true);
    int cbFileInfo = Marshal.SizeOf(info);

    SHGFI flags;
    if (bSmall)
    {
        flags = SHGFI.Icon | SHGFI.SmallIcon | SHGFI.UseFileAttributes;
    }
    else
    {
        flags = SHGFI.Icon | SHGFI.LargeIcon | SHGFI.UseFileAttributes;
    }

    SHGetFileInfo(strPath, 256, out info, (uint)cbFileInfo, flags);

    return Icon.FromHandle(info.hIcon);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top