C# File.Exists 判断系统文件,警惕32位和64位的差异
今天在调试一个Winform程序,使用File.Exists 判断一个已经存在的驱动文件,程序一直返回false。因为驱动文件属于系统目录,心想难道是权限不够导致的?然后用管理员身份运行软件,依然返回false。吓的我赶紧去系统目录C:\Windows\system32\drives 搜索该文件,一看在这里啊,怎么还是返回false。开始还以为VS出问题了,然后尝试判断一个D盘下的文件,发现可以判断成功。
判断代码如下
// 获取系统目录
var system = Environment.GetFolderPath(Environment.SpecialFolder.System);
var filePath = system + @"\drivers\evserial7.sys";
var flag = File.Exists(filePath);
MessageBox.Show("系统路径:" + filePath + "\r\n" + "checkDrives:" + flag);
运行结果

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

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

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

Release反编译

这样看两者并没有任何差异,因为我们判断是路径,所以我们只看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。

为什么当我用Release又能判断正确,原因在于上图的这个生成配置页面在Release的时候目标平台任然是:Any CPU。(不是X86),所以能判断成功。当把Release模式的目标平台改为X86后结果就是flase了。
那么编译的32位程序到底该怎么判断64位系统中的系统文件呢?其实当我们32位应用程序访问system32文件夹的时候,64位系统会自动帮我们自动重定向到SysWoW64文件夹。通过专业解释该文件夹主要是被设计用来处理许多在32-bit Windows和64-bit Windows之间的不同的问题,使得可以在64-bit Windows中运行32-bit程序。
所以我们在32位程序的时候判断系统路径其实已经重定向到了: C:\Windows\SysWoW64\drivers\evserial7.sys,这是系统自动重定向,所以IL代码中我们也看不到差异。这个目录肯定不存我们的文件,所以导致返回判断false。
那我们如何在32位下真正的访问system32目录呢?不要系统重定向。使用 C:\Windows\SysNative路径,这是个虚拟路径,我们在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 + @"\Sysnative\drivers\evserial7.sys";
var flag = File.Exists(filePath);
MessageBox.Show("系统路径:" + filePath + "\r\n" + "checkDrives:" + flag);
运行结果

C# File.Exists 判断系统文件,警惕32位和64位的差异的更多相关文章
- JAVA判断32位还是64位,调用不同的DLL(转)
源:JAVA判断32位还是64位,调用不同的DLL 通过获取sun.arch.data.model可判断是32还是64的JAVA 将32或者64位的DLL放不同的目录,实现自适应调用DLL Prope ...
- 如何判断你的windows系统是32位还是64位?
[学习笔记] 如 何判断你的windows系统是32位还是64位? java -version时,如果没有64就是32位的.eclipse.ini中如果没有64,就是32位的.但是我们的ini文件里面 ...
- 如何判断系统是32位还是64位的linux系统
如何判断系统是32位还是64位的linux系统 某日,需要下载个安装包,忽然忘记了自己的系统是32位还是64位的系统了,一时想不起来怎么查看时32位还是64位,呵呵,随便百度下,就发现有好多方法,这里 ...
- VC++ 判断当前系统为32位还是64位
尝试了在VC++环境下判断系统为32位还是64位的方法,亲测有效!提供的函数如下 BOOL IsWow64() { typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) ...
- 32位和64位dll判断
如何判断一个dll文件是32位还是64位? 1. 开发中经常会使用到VC的一个工具 Dependency Walker用depends.exe打开dll,文件名前有64标示的即为64位. 但是这个方式 ...
- C#判断操作系统是32位还是64位(超简单)
由于项目需要在64位和32位系统运行,需要判断当前系统是32位还是64位. 网上很多方法,但是都感觉不是很简洁,最后发现可以使用int的长度来判断:看代码 /// <summary> ...
- 判断 Windows操作系统是32位还是64位
function IsWin64: Boolean; var Kernel32Handle: THandle; IsWow64Process: function(Handle: Windows.THa ...
- C#如何判断操作系统位数是32位还是64位
方法一: 对于C#来说,调用WMI是一种简单易行的方式.我们可以用Win32_Processor类里面的AddressWidth属性来表示系统的位宽.AddressWidth的值受CPU和操作系统的双 ...
- [转]C#如何判断操作系统位数是32位还是64位
方法一: 对于C#来说,调用WMI是一种简单易行的方式.我们可以用Win32_Processor类里面的AddressWidth属性来表示系统的位宽.AddressWidth的值受CPU和操作系统的双 ...
随机推荐
- 【秒懂Java】【第1章_初识Java】02_软件开发
通过上一篇文章<01_编程语言>,我们了解到 Java是众多编程语言中的其中一种 编程语言可以用来开发软件 因此,我们即将要学习的Java技术,是属于软件开发的范畴.那软件开发的前景如何呢 ...
- 深入解读Dictionary
Dictionary<TKey,TValue>是日常.net开发中最常用的数据类型之一,基本上遇到键值对类型的数据时第一反应就是使用这种散列表.散列表特别适合快速查找操作,查找的效率是常数 ...
- .net core docker容器编排部署(linux)
环境准备 需要一个linux操作系统:我这里用的是ubuntu 18.04,安装步骤就不说了,网上很多教程,当然也可以私信我. 既然需要用到docker,那么就安装个docker,apt instal ...
- ASP.NET 开源导入导出库Magicodes.IE 多Sheet导入教程
多Sheet导入教程 说明 本教程主要说明如何使用Magicodes.IE.Excel完成多个Sheet数据的Excel导入. 要点 多个相同格式的Sheet数据导入 多个不同格式的Sheet数据导入 ...
- 问题记录--jekyll serve 启动的时候如何指定80端口
jekyll serve --host 0.0.0.0 --port 80 启动失败
- Apache DolphinScheduler(海豚调度) - 1.3 系列核心表结构剖析
Apache DolphinScheduler 是一个分布式去中心化,易扩展的可视化 DAG 工作流任务调度系统.致力于解决数据处理流程中错综复杂的依赖关系,使调度系统在数据处理流程中开箱即用. 近日 ...
- css3条件判断_@supports的用法/Window.CSS.supports()的使用
为了判断浏览器是否支持css3的一些新属性样式,当不兼容该样式的时候,我们可以更优雅的降级处理.这就需要使用到css3的条件判断功能:在css中支持@supports标记.或者在js中使用CSS.su ...
- 深入Mybatis源码——执行流程
前言 上一篇分析Mybatis是如何加载解析XML文件的,本篇紧接上文,分析Mybatis的剩余两个阶段:代理封装和SQL执行. 正文 代理封装 Mybatis有两种方式调用Mapper接口: pri ...
- redis cluster info显示cluster_state:fail解决方案
1.查看错误信息: 1.1 错误信息(1) 127.0.0.1:7000> get name (error) CLUSTERDOWN The cluster is down 127.0.0.1: ...
- scala 数据结构(十):折叠、扫描、拉链(合并)、迭代器
1 折叠 fold函数将上一步返回的值作为函数的第一个参数继续传递参与运算,直到list中的所有元素被遍历. 1)可以把reduceLeft看做简化版的foldLeft. 如何理解: def redu ...