Besoin Exemple de travail de ExtractAssociatedIcon de Shell32 Fonction .NET

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

  •  22-09-2019
  •  | 
  •  

Question

J'ai besoin d'un exemple de travail de la fonction ExtractAssociatedIcon dans Shell32.dll. Je ne peux pas le faire fonctionner et je suis d'idées. Je besoin d'un autre ensemble d'yeux sur le code suivant. Lorsque les charges de forme, son icône doit être réglé sur l'icône Visual Studio, mais tout ce que je reçois est l'icône par défaut du système.

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

Correction

<MarshalAs(UnmanagedType.LPStr)> était le problème. Il aurait dû être LPTStr, pas LPStr.

Était-ce utile?

La solution

Passing dans la poignée est certainement faux, le 1er argument est EAI une poignée de module, pas une poignée d'icônes. Cela a bien fonctionné:

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

Pas besoin de StringBuilder si la poignée du module est nul. Ne pas utiliser ce code si vous ne l'argument « index ». Icon.ExtractAssocationIcon fonctionnera tout aussi bien.

Autres conseils

Pourquoi ne pas utiliser simplement la méthode Icon.ExtractAssociatedIcon native .NET, qui semble faire la même chose?

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

P.S .: J'ai essayé votre code, avec le résultat même, mauvais que vous avez décrit. L'extrait de code ci-dessus semble fonctionner bien.

Essayez la méthode native .NET stakx mentionne - j'ai eu la chance de retour avec elle d'enregistrer le fichier ICO bien (si vous enregistrez comme un autre format, par exemple bitmap, il fonctionne normalement bien)

Pour une somethign PInvoke comme cela devrait fonctionner: (mise en garde, non testé) référencé: 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);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top