c# - 使用 AsParallel() 时无法获取与 Windows 应用程序关联的文件的文件图标

标签 c# .net wpf windows plinq

我想显示与文件关联的图标。这对于与普通桌面应用程序关联的文件类型不是问题,但仅对于与(都市/现代)应用程序关联的文件类型而言。

如果文件类型与应用相关联并且我正在使用AsParallel(),我只会得到默认的未知文件类型图标。澄清一下,我没有得到 null 或空图标,而是显示空白纸张的默认图标。如果没有 AsParallel(),我会得到正确的图标。

我尝试了其他几种获取图标的方法,例如 SHGetFileInfo() 或直接通过 dll 调用 ExtractAssociatedIcon()。行为始终相同。

示例:如果“Adobe Acrobat”是 PDF 文件的默认应用程序,那么在这两种情况下我都会得到正确的 Adob​​e PDF 图标。如果 Windows 8 或 10 中的内置(现代 UI)应用程序“阅读器”是默认应用程序,则在应用 AsParallel() 时我会看到未知文件类型图标。

MCVE

XAML:

<Window x:Class="FileIconTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <TextBox x:Name="TxtFilename" Text="x:\somefile.pdf"/>
        <Button Click="Button_Click">Go</Button>
        <Image x:Name="TheIcon" Stretch="None"/>
    </StackPanel>
</Window>

对应代码:

private void Button_Click(object sender, RoutedEventArgs e)
{
    var list = new List<string>();
    list.Add(TxtFilename.Text);

    var icons = list.AsParallel().Select(GetIcon); // problem with apps
//  var icons = list.Select(GetIcon);              // works always
    TheIcon.Source = icons.First();
}

public static ImageSource GetIcon(string filename)
{
    var icon = System.Drawing.Icon.ExtractAssociatedIcon(filename);
    var iSource = Imaging.CreateBitmapSourceFromHIcon(icon.Handle, Int32Rect.Empty,
        BitmapSizeOptions.FromEmptyOptions());
    iSource.Freeze();
    return iSource;
}

使用说明:仅使用两种变体中的一种。如果两者都执行,即使使用不同的变量,问题也可能无法重现。

最佳答案

那是因为 SHGetFileInfo(或 ExtractAssociatedIcon,它在内部使用 SHGetFileInfo)只在 STA 线程(单线程单元)上工作。在 MTA 线程(多线程单元)上,它只返回默认图标。 AsParallel 使用线程池中的工作线程,它们是 MTA。

关于c# - 使用 AsParallel() 时无法获取与 Windows 应用程序关联的文件的文件图标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31931508/

相关文章:

c# - Premake 无法为 C# 库创建 Makefile

c# - 观察集合中项目的 PropertyChanged

wpf - 如何将多个值绑定(bind)到单个 WPF TextBlock?

c# - HttpWebResponse 输出流不关闭

c# - 每次如何重新协商 SSL 连接 = 不同的 ssl-SessionID(windows,c#)

c# - Xamarin - NavigationPage.TitleView 内的 StackLayout 不会使用所有空间吗?

c# - MonoDevelop 用于 Linux 上的 .NET 应用程序

c# - 以编程方式在按钮上设置图像

C# 交互窗口丢失方法

c# - String.Format() 中的间距