我想显示与文件关联的图标。 对于与普通桌面应用程序相关联的文件types,这不是问题,而只适用于与(metro / modern)应用程序相关的文件types。
如果文件types与应用程序关联, 并且使用AsParallel() ,则只会获取默认的未知文件types图标。 为了说明,我不会得到null或图标,而是显示空白纸张的默认图标。 没有AsParallel()我得到正确的图标。
我尝试了其他几种方法来获取图标,例如, SHGetFileInfo()或通过dll直接调用ExtractAssociatedIcon() 。 行为总是一样的。
示例 :如果“Adobe Acrobat”是PDF文件的默认应用程序,则在这两种情况下我都会得到正确的Adobe PDF图标。 如果Windows 8或10中的内置(现代UI)应用程序“Reader”是默认应用程序,则在应用AsParallel()时,将获得未知文件types图标。
确保生成的进程的窗口在主应用程序的前面?
如何通过索引访问数据中继器的项目而不是显式名称?
安装程序如何检查程序集是否安装在GAC中,如果是,它的版本是什么?
以编程方式隐藏PropertyGrid中的属性
从cmd分析.NET应用程序:对于x64,缺lessvsperf.exe
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; }
使用说明:只使用两种变体中的一种。 如果两者都执行,即使有不同的variables,问题可能是不可重现的。
当有人试图运行我的.net桌面应用程序时,如何强制“运行方式”表单出现?
创build互斥锁时,“找不到path的一部分”错误
帮助debuggingInterop问题的最佳工具
如果在.NET中validation文件的签名是否存储在系统的目录存储中?
断开数据Windows程序使用sql Server Compact
这是因为SHGetFileInfo (或ExtractAssociatedIcon ,内部使用SHGetFileInfo )只适用于STA线程(单线程单元)。 在MTA线程(多线程单元)上,它只是返回默认图标。 AsParallel使用来自线程池(MTA)的工作线程。
托马斯的答案基本上是正确的,使用STA线程解决了这个问题。 知道了问题的原因, 这个答案暗示我在正确的方向。 通过使用STA线程的TaskScheduler,我可以使用Parallel.ForEach()来运行我的代码。
从这里的StaTaskScheduler (更多信息: MSDN博客文章 ),下面的代码解决了我的问题。
var list = new List<string>(); list.Add(TxtFilename.Text); var ts = new StaTaskScheduler(Environment.ProcessorCount); // can be saved for later reuse var icons = new ConcurrentBag<ImageSource>(); var pOptions = new ParallelOptions { TaskScheduler = ts }; Parallel.ForEach(list,pOptions,file => icons.Add(GetIcon(file))); TheIcon.source = icons.First();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。