[WPF Bug清单]之(3)——暗中创建文件的打开文件对话框

这个Bug可以简单描述为:在使用OpenFileDialog尝试打开一个不存在的文件的时候,OpenFileDialog本身会创建这个不存在的文件并删除它,然后告诉用户这个文件不存在。

 

下面我们来写个程序来重现这个Bug。基本原理是使用FileSystemWatcher来监视文件夹。

 

创建使用了如图1所示的程序。

 

1. 示例程序

 

首先选择一个文件夹,并监视里面的文件改变。

 

2. 监视文件夹

 

然后在被监视的文件中尝试打开一个不存在的文件。这个打开文件对话框已经设置CheckFileExistsCheckPathExiststrue

方法很简单,只要在File Name中随便输入一个不存在的文件名,然后点打开就可以了。如图3所示。

 

3. 打开不存在的文件

 

然后打开文件对话框“貌似”很乖地弹出了一个消息框,说文件不存在。如图4

 

 

4. 文件不存在消息框

 

然后我们点取消。但是,我们会发现后面的Output Message里有了变化。如图5所示。

 

5. 不合理的文件创建与删除

 

由于打开文件对话框实际就是一个API调用。没有像Reflactor一样的简单的方式去看它的实现。

 

而且在源代码中,也加入了FileIOPermission来禁向监视文件中写入。但是完全没有效果。其实这也算是另一个安全漏洞。因为.NET Framework在调用API之前应该对相关Permission进行检查。但是事实上没有进行这样的检查。(也许MS有其它方面的考虑吧)

 

PSWinForm中的打开文件对话框也有这样的问题,所以也不能完全算WPF的BUG,但是毕竟在WPF的Assembly里有这个问题,就放了进来。(没有看代码,应该是调用的一个API

 

同系列的其它文章:

[WPF Bug清单]()与之(1)——可以多选的单选ListBox

[WPF Bug清单](2)——RadioButtonIsChecked绑定失效

[WPF Bug清单](4)——点击RadioButton的空白没有反应

[WPF Bug清单](5)——隐藏模态对话框后变成非模态

[WPF Bug清单](6)——ButtonIsCancel属性失效

[WPF Bug清单](7)——顽固的Error Template

[WPF Bug清单](8)——RowDefinitionMaxHeight在一定条件下失效

[WPF Bug清单](9)——消失的光标

标签: WPF Bug
posted @ 2008-12-20 22:19 南柯之石 阅读(1795) 评论(10) 编辑 收藏

 回复 引用 查看   
#1楼 2008-12-20 23:02 周巍      
I think that this problem is caused by Windows, but not .NET APIs. Because this is an invocation of Windows API, and the behavior of different Windows versions may also differ from each other.
 回复 引用 查看   
#2楼 2008-12-20 23:35 大坏蛋      
为什么没有怀疑FileSystemWatcher呢?有没有尝试打开光盘上的文件呢?
 回复 引用 查看   
#3楼 2008-12-21 11:45 G yc {Son of VB.NET}      
和一楼的想法一样。

这原因应该是 Windows 问题,
Windows那个控件就是尝试建立,来检测是否存在文件的
至于那个文件, 就是 光荣的 Explorer.EXE

如果你用Win 2008 Core ,没有那个文件后, 就连运行里面浏览,点了都没有反应。。。。

 回复 引用 查看   
#4楼[楼主] 2008-12-21 14:07 南柯之石      
@周巍
As you said, the behavior of different version of Windows differ from each other. I just found that this bug doesn't exist on Windows Vista.

 回复 引用 查看   
#5楼[楼主] 2008-12-21 14:30 南柯之石      
@大坏蛋
谢谢你的提醒,试了下打开光盘上的文件。是不存在这个问题的。
但是在XP系统上打开光盘上一个不存在的文件的消息框有所不同。



而在Vista系统上,消息框也是与打开磁盘上不存在文件是一样的。

看来Vista系统对于OpenFileDialog的API进行了改进。

至于有没有可能是FileSystemWatcher的问题。从逻辑上来讲应该不是,对于一个设计良好的API,FileSystemWatcher的行为是不应该受到OpenFileDialog影响的。所以最好的结果是:OpenFileDialog用类似下面的错误逻辑进行的文件存在性的验证。

bool IsExist(string path)
try
{
    CreateFile(path)
    return false;
}
catch(FileExistsException)
{
    return true;
}
finally
{
    Delete(path)
}

 回复 引用 查看   
#6楼 2008-12-21 21:26 G yc {Son of VB.NET}      
这个代码有问题吧
bool IsExist(string path)
try
{
CreateFile(path)
return false;
}
catch(FileExistsException)
{
return true;
}
finally
{
Delete(path)
}


这么做的话, 不是每次都删除了?

 回复 引用 查看   
#7楼[楼主] 2008-12-21 21:34 南柯之石      
@G yc {Son of VB.NET}
所以我说“类似”。(特意加了黑体)……

重点在于OpenFileDialog用创建文件的方式来测试文件是否已经存在。
示例而已。

本来是想加个Check,不过怕代码长了让人懒得看,就没加。

会意代码。

 回复 引用 查看   
#8楼 2008-12-21 21:38 G yc {Son of VB.NET}      
^_^~

类似,让我给 无视了~~~

 回复 引用   
#9楼 2009-01-11 23:26 xiongli lixiong[未注册用户]
打开文件只有一个API:
CreateFileEx

 回复 引用 查看   
#10楼[楼主] 2009-01-12 21:50 南柯之石      
@xiongli lixiong
但是还没有到打开文件的时候,只是检查文件是否存在。