asp.net SHGetFileInfo [вызов winapi] - PullRequest
0 голосов
/ 20 октября 2010

Мне нужен файл дерева на моем сайте asp.net. Для получения иконок я пытаюсь использовать функцию API SHGetFileInfo. На не asp.net приложение работает хорошо, возвращает исправляет Icon. Когда я размышляю об этом в контексте asp.net, я получаю:

Попытка чтения или записи в защищенную память.

Что не так? Могу ли я получить значок поля в контексте asp.net?

Код:

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

1 Ответ

1 голос
/ 21 октября 2010

Подпись P / Invoke, которую вы используете для SHGetFileInfo, неверна - используйте на PInvoke.net .

SHGetFileInfo возвращает значение, которое вы должны проверитьуспех, прежде чем вы получите доступ к возвращенным данным.В случае сбоя вызова API результаты доступа к ожидаемому значку непредсказуемы (и обычно плохие).

Как только вы узнаете, в чем заключается ошибка, вы можете заняться исправлением этой проблемы.Вы никогда не должны пропускать код проверки ошибок, когда вызываете Win32 API из управляемого кода.Прочитайте MSDN документы , что указывает на успех и какие ошибки следует ожидать.

В вашем случае:

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

должно выглядеть следующим образом

    IntPtr result = SHGetFileInfo(strPath, 256, out info, (uint)cbFileInfo, flags);
    if (result != IntPtr.Zero)
    {
      return Icon.FromHandle(info.hIcon);
    }
    else
    {
      // add error handling here
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...