C# File.Exists判断系统文件 警惕32位和64位的差异

Posted DotNet

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# File.Exists判断系统文件 警惕32位和64位的差异相关的知识,希望对你有一定的参考价值。

(给DotNet加星标,提升.Net技能

转自:Cfan1236
cnblogs.com/rui1236/p/13381322.html

前言


在调试一个Winform程序,使用File.Exists 判断一个已经存在的驱动文件,程序一直返回false。


因为驱动文件属于系统目录,心想难道是权限不够导致的?然后用管理员身份运行软件,依然返回false。


吓的我赶紧去系统目录C:Windowssystem32drives 搜索该文件,一看在这里啊,怎么还是返回false。


开始还以为VS出问题了,然后尝试判断一个D盘下的文件,发现可以判断成功。


判断代码如下


// 获取系统目录
var system = Environment.GetFolderPath(Environment.SpecialFolder.System);

var filePath = system + @"driversevserial7.sys";
var flag = File.Exists(filePath);
MessageBox.Show("系统路径:" + filePath + " " + "checkDrives:" + flag);


运行结果



在系统中找文件确实存在,如下图


C# File.Exists判断系统文件 警惕32位和64位的差异


奇怪在于当我把程序设置成Release运行的时候判断又成功了,第一张图Debug运行的,下图是Release


C# File.Exists判断系统文件 警惕32位和64位的差异


当时心想为什么Release和Debug不一样呢,一时有点诧异,然后就想着,看看反编译后的IL代码,看两者是不是有什么差别?


Debug反编译


C# File.Exists判断系统文件 警惕32位和64位的差异


Release反编译


C# File.Exists判断系统文件 警惕32位和64位的差异


这样看两者并没有任何差异,因为我们判断是路径,所以我们只看IL中路径是否有不同编译, 两者中IL_0002: call string [mscorlib]System.Environment::GetFolderPath(valuetype [mscorlib]System.Environment/SpecialFolder)都是一样的,说明系统路径一样,后面拼接字符串更加不会有任何差别。


最终通过stackoverflow找到原因,因为我当前程序编译的是32位即X86,32位应用程序在64位系统中是无法访问system32目录的。为什么我程序要选择编译32位呢,因为我程序当中需要调用一个C++写的dll,该dll是32位的,我无法改变。如果我程序编译时选择AnyCPU或者X64,那么该dll是无法调用的。所以我只能改成X86。


C# File.Exists判断系统文件 警惕32位和64位的差异


为什么当我用Release又能判断正确,原因在于上图的这个生成配置页面在Release的时候目标平台任然是:Any CPU。(不是X86),所以能判断成功。当把Release模式的目标平台改为X86后结果就是false了。


那么编译的32位程序到底该怎么判断64位系统中的系统文件呢?其实当我们32位应用程序访问system32文件夹的时候,64位系统会自动帮我们自动重定向到SysWoW64文件夹。


通过专业解释该文件夹主要是被设计用来处理许多在32-bit Windows和64-bit Windows之间的不同的问题,使得可以在64-bit Windows中运行32-bit程序。


所以我们在32位程序的时候判断系统路径其实已经重定向到了:  C:WindowsSysWoW64driversevserial7.sys,这是系统自动重定向,所以IL代码中我们也看不到差异。这个目录肯定不存我们的文件,所以导致返回判断false。


那我们如何在32位下真正的访问system32目录呢?不要系统重定向。


使用 C:WindowsSysNative路径,这是个虚拟路径,我们在Windows资源管理器中是无法找到的。但是他最终还是会指向到system32中。SysNative文件夹目的就是让32位应用程序访问64位系统文件的方法。


现在我将代码改下,前面的 Environment.GetFolderPath(Environment.SpecialFolder.System)是获取system32这里要改为Environment.SpecialFolder.Windows,获取windows目录,并在下面拼接上Sysnative目录。


这只是在判断系统文件的时候会存在32位和64位的差异,普通文件就不存在任何影响了。


最后修改代码如下


// 获取windows目录
var system = Environment.GetFolderPath(Environment.SpecialFolder.Windows);
var filePath = system + @"Sysnativedriversevserial7.sys";
var flag = File.Exists(filePath);
MessageBox.Show("系统路径:" + filePath + " " + "checkDrives:" + flag);


运行结果



- EOF -



推荐阅读   点击标题可跳转


看完本文有收获?请转发分享给更多人

关注「DotNet」加星标,提升.Net技能 

好文章,我在看❤️

以上是关于C# File.Exists判断系统文件 警惕32位和64位的差异的主要内容,如果未能解决你的问题,请参考以下文章

C#如何用exists判断指定路径的文件是不是存在。求完整代码?

C# File.Exists 返回 false,文件确实存在

File.Exists判断文件是不是存在总是返回False?

C#,判断是文件还是文件夹。

C#删除文件

c#中如何检测文件路径是不是存在