2010-10-20 5 views
0

J'ai besoin d'un fichier arborescence sur mon site asp.net. Pour obtenir des icônes, j'essaie d'utiliser la fonction api SHGetFileInfo. Dans l'application non asp.net cela fonctionne bien, les retours corrige l'icône. Quand je le conusme au contexte asp.net j'ai obtenu:asp.net SHGetFileInfo [appel winapi]

Vous avez tenté de lire ou d'écrire de la mémoire protégée.

Qu'est-ce qui ne va pas? Puis-je obtenir une icône de fiel sur le contexte d'asp.net?

code:

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

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

     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; 
    }; 

    public const uint SHGFI_ICON = 0x000000100; // get icon 
    public const uint SHGFI_DISPLAYNAME = 0x000000200; // get display name 
    public const uint SHGFI_TYPENAME = 0x000000400; // get type name 
    public const uint SHGFI_ATTRIBUTES = 0x000000800; // get attributes 
    public const uint SHGFI_ICONLOCATION = 0x000001000; // get icon location 
    public const uint SHGFI_EXETYPE = 0x000002000; // return exe type 
    public const uint SHGFI_SYSICONINDEX = 0x000004000; // get system icon index 
    public const uint SHGFI_LINKOVERLAY = 0x000008000; // put a link overlay on icon 
    public const uint SHGFI_SELECTED = 0x000010000; // show icon in selected state 
    public const uint SHGFI_ATTR_SPECIFIED = 0x000020000; // get only specified attributes 
    public const uint SHGFI_LARGEICON = 0x000000000; // get large icon 
    public const uint SHGFI_SMALLICON = 0x000000001; // get small icon 
    public const uint SHGFI_OPENICON = 0x000000002; // get open icon 
    public const uint SHGFI_SHELLICONSIZE = 0x000000004; // get shell size icon 
    public const uint SHGFI_PIDL = 0x000000008; // pszPath is a pidl 
    public const uint SHGFI_USEFILEATTRIBUTES = 0x000000010; // use passed dwFileAttribute 
    public const uint SHGFI_ADDOVERLAYS = 0x000000020; 
    public const uint SHGFI_OVERLAYINDEX = 0x000000040; 

    private static Icon GetIcon(string strPath, uint flags) 
    { 
     SHFILEINFO info = new SHFILEINFO(true); 
     int cbFileInfo = Marshal.SizeOf(info); 

     SHGetFileInfo(strPath, 256, out info, (uint)cbFileInfo, flags); 
     return Icon.FromHandle(info.hIcon); 
    } 

    /// <summary> 
    /// Get the associated Icon for a file or application, this method always returns 
    /// an icon. If the strPath is invalid or there is no idonc the default icon is returned 
    /// </summary> 
    /// <param name="strPath">full path to the file</param> 
    /// <param name="bSmall">if true, the 16x16 icon is returned otherwise the 32x32</param> 
    /// <returns></returns> 
    public static Icon GetIcon(string strPath, bool bSmall) 
    { 
     uint flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES; 
     flags |= bSmall ? SHGFI_SMALLICON : SHGFI_LARGEICON; 
     return GetIcon(strPath, flags); 
    } 

    public static Icon GetIcon(string strPath, bool bSmall, bool bOpened) 
    { 
     uint flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES; 
     flags |= bSmall ? SHGFI_SMALLICON : SHGFI_LARGEICON; 
     flags |= bOpened ? SHGFI_OPENICON : 0; 
     return GetIcon(strPath, flags); 
    } 
} 
+0

Avez-vous l'esprit pour poster votre code problématique? – Vantomex

+0

C'est utile pour nous si vous pouvez aussi poster votre déclaration 'SHGetFileInfo()'. – Vantomex

+0

Quelle architecture ASP.NET et ordinateur exécutez-vous, 32 bits ou 64 bits? parce que la valeur de retour de 'SHGetFileInfo()' est un 'DWORD_PTR', pas' int'. Le type 'DWORD_PTR' est un type spécial, c'est un' DWORD' dans l'architecture 32 bits, et c'est un 'DWORD64' dans l'architecture 64 bits. – Vantomex

Répondre

1

Le P/Invoke signature que vous utilisez pour SHGetFileInfo ne va pas - utiliser une at PInvoke.net.

SHGetFileInfo renvoie une valeur dont vous devez vérifier la réussite avant d'accéder aux données renvoyées. Si l'appel de l'API échoue, les résultats de l'accès à l'icône attendue sont imprévisibles (et généralement mauvais). Une fois que vous connaissez l'erreur, vous pouvez résoudre ce problème séparément. Vous ne devez jamais omettre le code de vérification d'erreur lors de l'appel de l'API Win32 à partir du code managé. Lisez le MSDN docs pour ce qui indique le succès et les erreurs à attendre.

Dans votre cas:

SHGetFileInfo(strPath, 256, out info, (uint)cbFileInfo, flags); 
    return Icon.FromHandle(info.hIcon); 

devrait ressembler à ceci

IntPtr result = SHGetFileInfo(strPath, 256, out info, (uint)cbFileInfo, flags); 
    if (result != IntPtr.Zero) 
    { 
     return Icon.FromHandle(info.hIcon); 
    } 
    else 
    { 
     // add error handling here 
    }