无法关闭SHGetFileInfo
本文关键字:SHGetFileInfo | 更新日期: 2023-09-27 18:22:21
我有一种很好的技术可以在当前系统中获得相关的扩展/映像(因为扩展在不同的系统中可能有不同的映像)。这里有一个功能:
public static Icon getIconFromFile(string ext, bool large = true)
{
string fileName = (new Random()).Next(100, 1000).ToString() + ext;
System.IO.File.Create(fileName);
System.Drawing.Icon icon;
SHFILEINFO shinfo = new SHFILEINFO();
if (large)
{
IntPtr hImgLarge = Win32.SHGetFileInfo(fileName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_ICON | Win32.SHGFI_LARGEICON);
icon = System.Drawing.Icon.FromHandle(shinfo.hIcon);
}
else
{
IntPtr hImgSmall = Win32.SHGetFileInfo(fileName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_ICON | Win32.SHGFI_SMALLICON);
icon = System.Drawing.Icon.FromHandle(shinfo.hIcon);
}
try
{
System.IO.File.Delete(fileName);
}
catch(Exception e)
{
System.Console.WriteLine(e.StackTrace);
}
return icon;
}
问题是函数没有关闭对文件的访问,所以我无法删除它。我该怎么办?感谢
您不需要创建一个伪文件。使用SHGFI_USEFILEATTRIBUTES。
File.Create
返回一个引用您创建的文件的流。为了确保流正确关闭,您应该将其封装在using
块中:
System.Drawing.Icon icon;
using(var stream = System.IO.File.Create(fileName))
{
SHFILEINFO shinfo = new SHFILEINFO();
if (large)
{
IntPtr hImgLarge = Win32.SHGetFileInfo(fileName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_ICON | Win32.SHGFI_LARGEICON);
icon = System.Drawing.Icon.FromHandle(shinfo.hIcon);
}
else
{
IntPtr hImgSmall = Win32.SHGetFileInfo(fileName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_ICON | Win32.SHGFI_SMALLICON);
icon = System.Drawing.Icon.FromHandle(shinfo.hIcon);
}
}
try
{
System.IO.File.Delete(fileName);
}
catch(Exception e)
{
System.Console.WriteLine(e.StackTrace);
}
return icon;
是否使用返回的流并不重要,您需要确保它已被处理,以便可以删除文件。还要注意,我已经将icon
的声明移到了using
块之外,这样您就可以在方法的末尾返回它。
我还应该指出:
string fileName = (new Random()).Next(100, 1000).ToString() + ext;
当你可以很容易地调用"System.IO.Path.GetTempFileName();",并将创建文件并将其唯一命名给操作系统,而不是自己尝试这样做时,这有点"坏主意"。THat还有一个额外的好处,那就是在用户temp
目录中创建文件,考虑到它是一个临时文件,这是它的最佳位置。您也不会遇到文件被打开的问题(有各种其他方法,如System.IO.Path.GetExtension
,可以用来重命名文件,使其具有适当的扩展名。