C# WINAPI调用中的错误能否停止BackgroundWorker中代码的执行?
我的应用程序列出了所有带有默认图标的文件扩展名。在应用程序启动时,我使用BackgroundWorker获取所有文件扩展名及其相关图标。一些用户报告说,应用程序无限显示加载屏幕,没有崩溃或异常。因此,我删除了获取与文件扩展名相关的图标的部分,所有这些图标都可以正常工作 下面是BackgroundWorker的代码C# WINAPI调用中的错误能否停止BackgroundWorker中代码的执行?,c#,winapi,pinvoke,backgroundworker,C#,Winapi,Pinvoke,Backgroundworker,我的应用程序列出了所有带有默认图标的文件扩展名。在应用程序启动时,我使用BackgroundWorker获取所有文件扩展名及其相关图标。一些用户报告说,应用程序无限显示加载屏幕,没有崩溃或异常。因此,我删除了获取与文件扩展名相关的图标的部分,所有这些图标都可以正常工作 下面是BackgroundWorker的代码 var backgroundWorker = new BackgroundWorker(); var progressDialog = new ProgressDialog(); ba
var backgroundWorker = new BackgroundWorker();
var progressDialog = new ProgressDialog();
backgroundWorker.DoWork += (o, args) =>
{
FileExtension.GetFileExtensions();
GetImages();
};
backgroundWorker.RunWorkerCompleted += (o, args) =>
{
Toggle();
progressDialog.Close();
};
backgroundWorker.RunWorkerAsync();
progressDialog.ShowDialog();
但我想知道我使用以下代码来获得图像。WINAPI调用中的错误是否会停止BackgroundWorker的执行
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
}
[Flags]
enum FileInfoFlags
{
ShgfiIcon = 0x000000100,
ShgfiUsefileattributes = 0x000000010
}
[DllImport("Shell32", CharSet = CharSet.Auto)]
extern static IntPtr SHGetFileInfo(
string pszPath,
int dwFileAttributes,
out SHFILEINFO psfi,
int cbFileInfo,
FileInfoFlags uFlags);
public enum IconSize
{
Large = 0x000000000,
Small = 0x000000001
}
public static Image GetImageExtension(string fileExt, IconSize size)
{
var fileInfo = new SHFILEINFO();
SHGetFileInfo(fileExt, 0, out fileInfo, Marshal.SizeOf(fileInfo),
FileInfoFlags.ShgfiIcon | FileInfoFlags.ShgfiUsefileattributes | (FileInfoFlags)size);
try
{
return Icon.FromHandle(fileInfo.hIcon).ToBitmap();
}
catch (Exception)
{
return Resources.picture_16;
}
}
private static string TrimMatchingQuotes(this string input, char quote)
{
if ((input.Length >= 2) &&
(input[0] == quote) && (input[input.Length - 1] == quote))
return input.Substring(1, input.Length - 2);
return input;
}
private static Icon ExtractIcon(string file, int number, bool largeIcon)
{
IntPtr large;
IntPtr small;
ExtractIconEx(file, number, out large, out small, 1);
try
{
return Icon.FromHandle(largeIcon ? large : small);
}
catch
{
return null;
}
}
[DllImport("Shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern int ExtractIconEx(string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons);
[DllImport("shell32.dll")]
static extern IntPtr ExtractAssociatedIcon(IntPtr hInst, StringBuilder lpIconPath,
out ushort lpiIcon);
public static Image GetImage(string icon)
{
try
{
if (icon.Contains(","))
{
var split = icon.Split(new[] { ',' });
if (!string.IsNullOrEmpty(split[0]))
{
int index;
int.TryParse(split[1], out index);
var image =
ExtractIcon(Environment.ExpandEnvironmentVariables(split[0]).TrimMatchingQuotes('\"'),
index, false);
if (image != null)
return image.ToBitmap();
}
}
if (File.Exists(icon))
{
try
{
var image = Icon.ExtractAssociatedIcon(icon);
return image != null ? image.ToBitmap() : Resources.picture_16;
}
catch (ArgumentException)
{
var strB = new StringBuilder(icon);
ushort uicon;
var handle = ExtractAssociatedIcon(IntPtr.Zero, strB, out uicon);
return Icon.FromHandle(handle).ToBitmap();
}
}
return Resources.picture_16;
}
catch (Exception)
{
return Resources.picture_16;
}
}
我怀疑根本原因不在WINAPI中,而在bgw的使用方式中,所以发布bgw的代码?可能不相关,但您需要
DestroyIcon()
来自SHGetFileInfo/ExtractIconEx
发布的BackgroundWorker代码的句柄。在GetImages中,我使用foreach循环遍历列表中的每个文件扩展名,并使用上面提到的函数为ImageList获取图像。我从DoWork中删除了GetImages函数,这就成功了,所以我怀疑WinAPI代码。如果这种情况只发生在一个用户身上,那么请检查该用户安装了哪些Shell扩展。你可能会发现他们有一些管理图标或类似的东西。作为指导,如果一个问题只影响一个人,那么找出这个人与其他人的不同之处。