获取特殊文件夹的图标,例如我的电脑和图书馆
Getting Icon Of Special Folders Such As My Computer And Libraries
我一直在尝试构建一个 class 来简单地获取特殊文件夹的当前图标,例如 "My Computer" AKA "Computer"、"Libraries" 等。我'我目前正在尝试使用 SHGetFileInfo() API 来实现此目的。
微软页面上的原始SHGetFileInfo函数...
#1 代码块
DWORD_PTR SHGetFileInfo(
_In_ LPCTSTR pszPath,
DWORD dwFileAttributes,
_Inout_ SHFILEINFO *psfi,
UINT cbFileInfo,
UINT uFlags
);
(以上引用自:http://msdn.microsoft.com/en-us/library/windows/desktop/bb762179%28v=vs.85%29.aspx)
在另一个 SO 问题上,我发现这是一个例子...
#2 代码块
IntPtr pidl;
SHGetSpecialFolderLocation(0, CSIDL_DRIVES, pidl);
SHGetFileInfo(pidl, 0, shinfo, Marshal.SizeOf(shinfo), (SHGFI_PIDL | SHGFI_DISPLAYNAME | SHGFI_ICON | SHGFI_SMALLICON));
(以上引用自:)
描述了以需要第一个参数为 IntPtr 的方式使用 SHGetFileInfo。我的印象是第一个参数需要是基于此的字符串...
#3 代码块
[DllImport("shell32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags);
(以上引用自:http://pinvoke.net/default.aspx/shell32.SHGetFileInfo)
此外,环顾四周,我也找到了这个答案...
#4 代码块
[DllImport("Pdh.dll")]
static extern int PdhOpenQueryW(
[MarshalAs(UnmanagedType.LPWStr)] string szDataSource,
UIntPtr dwUserData,
out IntPtr phQuery);
(以上引用自:)
在上面的回答中,用户告诉原始发布者使用...
#5 代码块
[MarshalAs(UnmanagedType.LPWStr)] string
映射到
#6 代码块
"_In_ LPCTSTR pszPath,"
参数。在顶部的 MSDN c++ 构造函数中找到。这对我来说比任何一个都更有意义。但是我无法理解的是上面的答案(#2 代码块)告诉原始发布者在 pinvoke.net 网站说将其定义为字符串时使用 IntPtr。
知道如何让 SHGetFileInfo() 工作以获得该图标吗?谢谢!
更新
这是我尝试使用它的示例...
[DllImport("Shell32.dll")]
public static extern IntPtr SHGetFileInfo(
string pszPath,
uint dwFileAttributes,
ref SHFILEINFO psfi,
uint cbFileInfo,
uint uFlags
);
SHGetFileInfo((IntPtr)oTarget, 0, ref shfi, (uint)Marshal.SizeOf(shfi), flags);
然后我得到两个错误...
Error 1 The best overloaded method match for 'SHGetFileInfo(string, uint, ref SHFILEINFO, uint, uint)' has some invalid arguments C:\FakePath\ImageWorker.cs 67 25 ImageWorker
Error 2 Argument 1: cannot convert from 'System.IntPtr' to 'string' C:\FakePath\ImageTool.cs 67 47 ImageWorker
如何获取图标示例:
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
public string szDisplayName;
public string szTypeName;
};
SHFILEINFO shinfo= new SHFILEINFO();
SHGetFileInfo(@"...", 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), 0x000000100); //SHGFI_ICON
Icon icon = (Icon)Icon.FromHandle(shinfo.hIcon);
//use the icon and finally destroy it with:
DestroyIcon(shinfo.hIcon);
SHGetFileInfo
相当时髦。第一个参数是指向以 null 结尾的字符数组的指针,或者是 PIDL。在非托管代码中,参数被声明为以 null 结尾的字符数组。如果您想通过 PIDL,那么您需要进行演员表。
在 p/invoke 调用中,您不能使用转换。因此,您需要声明两个重载的 p/invoke 导入。一个以 string
作为第一个参数,另一个以 IntPtr
作为第一个参数。
我一直在尝试构建一个 class 来简单地获取特殊文件夹的当前图标,例如 "My Computer" AKA "Computer"、"Libraries" 等。我'我目前正在尝试使用 SHGetFileInfo() API 来实现此目的。
微软页面上的原始SHGetFileInfo函数...
#1 代码块
DWORD_PTR SHGetFileInfo(
_In_ LPCTSTR pszPath,
DWORD dwFileAttributes,
_Inout_ SHFILEINFO *psfi,
UINT cbFileInfo,
UINT uFlags
);
(以上引用自:http://msdn.microsoft.com/en-us/library/windows/desktop/bb762179%28v=vs.85%29.aspx)
在另一个 SO 问题上,我发现这是一个例子...
#2 代码块
IntPtr pidl;
SHGetSpecialFolderLocation(0, CSIDL_DRIVES, pidl);
SHGetFileInfo(pidl, 0, shinfo, Marshal.SizeOf(shinfo), (SHGFI_PIDL | SHGFI_DISPLAYNAME | SHGFI_ICON | SHGFI_SMALLICON));
(以上引用自:)
描述了以需要第一个参数为 IntPtr 的方式使用 SHGetFileInfo。我的印象是第一个参数需要是基于此的字符串...
#3 代码块
[DllImport("shell32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags);
(以上引用自:http://pinvoke.net/default.aspx/shell32.SHGetFileInfo)
此外,环顾四周,我也找到了这个答案...
#4 代码块
[DllImport("Pdh.dll")]
static extern int PdhOpenQueryW(
[MarshalAs(UnmanagedType.LPWStr)] string szDataSource,
UIntPtr dwUserData,
out IntPtr phQuery);
(以上引用自:)
在上面的回答中,用户告诉原始发布者使用...
#5 代码块
[MarshalAs(UnmanagedType.LPWStr)] string
映射到
#6 代码块
"_In_ LPCTSTR pszPath,"
参数。在顶部的 MSDN c++ 构造函数中找到。这对我来说比任何一个都更有意义。但是我无法理解的是上面的答案(#2 代码块)告诉原始发布者在 pinvoke.net 网站说将其定义为字符串时使用 IntPtr。
知道如何让 SHGetFileInfo() 工作以获得该图标吗?谢谢!
更新
这是我尝试使用它的示例...
[DllImport("Shell32.dll")]
public static extern IntPtr SHGetFileInfo(
string pszPath,
uint dwFileAttributes,
ref SHFILEINFO psfi,
uint cbFileInfo,
uint uFlags
);
SHGetFileInfo((IntPtr)oTarget, 0, ref shfi, (uint)Marshal.SizeOf(shfi), flags);
然后我得到两个错误...
Error 1 The best overloaded method match for 'SHGetFileInfo(string, uint, ref SHFILEINFO, uint, uint)' has some invalid arguments C:\FakePath\ImageWorker.cs 67 25 ImageWorker
Error 2 Argument 1: cannot convert from 'System.IntPtr' to 'string' C:\FakePath\ImageTool.cs 67 47 ImageWorker
如何获取图标示例:
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
public string szDisplayName;
public string szTypeName;
};
SHFILEINFO shinfo= new SHFILEINFO();
SHGetFileInfo(@"...", 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), 0x000000100); //SHGFI_ICON
Icon icon = (Icon)Icon.FromHandle(shinfo.hIcon);
//use the icon and finally destroy it with:
DestroyIcon(shinfo.hIcon);
SHGetFileInfo
相当时髦。第一个参数是指向以 null 结尾的字符数组的指针,或者是 PIDL。在非托管代码中,参数被声明为以 null 结尾的字符数组。如果您想通过 PIDL,那么您需要进行演员表。
在 p/invoke 调用中,您不能使用转换。因此,您需要声明两个重载的 p/invoke 导入。一个以 string
作为第一个参数,另一个以 IntPtr
作为第一个参数。