Hai bisogno di esempio funzionante di Funzione ExtractAssociatedIcon di Shell32 in .NET

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

  •  22-09-2019
  •  | 
  •  

Domanda

Ho bisogno di un esempio di lavoro della funzione ExtractAssociatedIcon in Shell32.dll. Non riesco a farlo funzionare e sono a corto di idee. Ho bisogno di un altro paio di occhi sul seguente codice. Quando il modulo viene caricato, la sua icona devono essere impostati allo Studio icona visiva, ma tutto quello che ottiene è l'icona di sistema predefinita.

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

Corretto

<MarshalAs(UnmanagedType.LPStr)> era il problema. Avrebbe dovuto essere LPTStr, non LPStr.

È stato utile?

Soluzione

Passaggio nel manico è sicuramente sbagliato, il primo argomento di EAI è un handle di modulo, non un manico un'icona. Questo ha funzionato bene:

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

Non c'è bisogno di StringBuilder se la maniglia del modulo è nullo. Non usare questo codice se non lo fai l'argomento "indice". Icon.ExtractAssocationIcon funzionerà altrettanto bene.

Altri suggerimenti

Perché non è sufficiente utilizzare il metodo Icon.ExtractAssociatedIcon nativo NET, che sembra fare la stessa cosa?

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

P.S .: Ho provato il codice, con lo stesso risultato, sbagliato che hai descritto. Il frammento di codice di cui sopra sembra funzionare, però.

Prova il metodo .NET nativo stakx menziona - ho avuto di nuovo fortuna con esso il salvataggio del file ICO anche (se si salva come un altro formato, ad esempio bitmap, normalmente funziona però)

Per un somethign PInvoke come questo dovrebbe funzionare: (avvertimento, non testato) si fa riferimento: 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);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top