前几天遇到了一个让我啼笑皆非的bug,我写的Wpf程序在Win7里能够运行,到XP、WindowsServer里运行点击某个控件以后闪退,不报任何错,在后台代码里trycatch也捕捉不到任何异常。很明显,这不是后台的代码出的错。当时状况很艰苦,用户在十万八千里以外,他的电脑上也没有调试环境,我只能在本地一步一步排除错误可能,修改、打包、发布到用户、卸载、重装、足足折腾了一天,最后总算是搞定了。服务器
不知道大牛们遇到这样的状况怎么处理。没有调试环境,本地运行良好,用户运行就闪退,没有任何错误抛出。你们先思考一番,你遇到这样的状况,你会如何处理。架构
我比较笨,第一步,把这个控件关联的后台代码注释,排除后台代码的出错可能。spa
第二步,既然不是后台代码的问题,那就是这个控件的问题了,这是个CheckBox,引用到一个写好的资源Style,因为不能到用户那里调试,本地也无缺运行,那我就在窗体的Loaded里找这个资源,代码赋给这个控件。果真,本地报了一个“{DependencyProperty.UnsetValue}”不是属性“BorderBrush”的有效值的错误,心中窃喜,一看BorderBrush后面赋值的资源,在那个资源文件里找不到,放在了App.xaml里,那也行,那就把它弄过来,放到Style同文件里,本地运行,Ok,发布给用户,继续闪退。debug
第三步,如今十有八九是这个Style的问题了,是什么问题呢?每次我只要一点击这个CheckBox就闪退,那我就到Style里看看,点击时会有一个向右下平移的TranslateTransform执行了,难道是它?无论,删了再说,发布,继续闪退。再看,Checked为True和False的时候操做了一个Path,难道是这里有问题?继续删,继续闪退。调试
到这我就有点抓狂了,好吧,既然这个Style有问题,不用你能够吧,把引用Style的语句移掉,OK了。orm
虽然是正常运行了,可是问题的根本没有解决,因为使用默认的风格影响了用户的使用,必须使用自定义Style。那好吧,不用那个有问题的Style,用Win7的,直接复制副本到资源文件里,仍是闪退。资源
我开始怀疑是否是系统有问题,用360修复了,问题依旧。io
Google,百度,好像没有人有我这样的遭遇,我开始同情本身了。form
蓦然回首,发如今不远处有台闲置的电脑,是部门的服务器,通常没人用,这让我看到了但愿,远程到这台电脑,它是WindowsServer2003,上面也没有VS2010,可是毕竟是局域网,直接debug文件夹拷上去运行,同样闪退。后台
难道是混在资源文件里会出错?好吧,单独给你弄个资源文件,继续闪退。
没辙了,这个Style到底哪里出了问题,不能老这样闪退啊,好歹给我报个错,要哭了...已经没有什么我能作的了。
这时候我在想,是否是这个资源要用到App.xaml里的资源,运行时引用不到?好歹是个机会,因而把App里的资源所有移到Merged的资源里,发布用户,运行OK,原来正是如此!
总结:Wpf程序操做控件闪退,通常是因为资源引发的,如Style里的资源名找不到,写在分资源文件里须要引用到App.xaml里的资源等等,这时候要作的就是整合资源,App里面的资源所有整合到各自的资源文件里。以下:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="SimpleStyles.xaml"/>
<ResourceDictionary Source="SpecalStyles.xaml"/>
<ResourceDictionary Source="WindowStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
建议:在程序架构刚刚搭建的时候就注意资源的分流,不要全挤在App.xaml里,App.xaml只做Merged,不是必须不在App.xaml里写任何资源,新手能够那样作,老手千万不要贻笑大方啊。