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集合框架 - Map接口
Map 接口大致说明(jdk11): 整体介绍: 一个将键映射到值的(key-value)对象, 键值(key)不能重复, 每个键值只能影射一个对象(一一对应). 这个接口取代了Dictionary类 ...
- 使用docker创建redis容器
1.拉取redis镜像
- xshell界面变成半透明的怎么办?
在工具——选项查看选项卡去掉使窗口透明的前的勾就可以了
- Zookeeper 序列化
读完这篇文章你将会收获到 在 Zookeeper 源码项目中新建模块,使用 Jute 进行序列化和反序列化 修改 Jute 中的 buffer size 来序列化/反序列化大对象 序言 从 前面的文章 ...
- Cypress与TestCafe WebUI端到端测试框架简介
近期接触了Cypress和TestCafe,两个测试框架都基于Node.js,都不再使用Selenium+WebDriver,而且开箱即用,非常轻量级,就冲着不再使用WebDriver这一点,极大地勾 ...
- css中input与button在一行高度不一致的解决方法
在写html表单的时候,发现了一个问题:input和button设置了一样的宽高,但是显示高度确不一致,先看代码: <style> input,button{ width:100px; h ...
- iframe 透明兼容,设置iframe透明背景的方法
从IE5.5+就支持iframe框架的背景透明.通过使用allowtransparency和background-color来设置iframe框架的透明效果,代码如下: <iframe src= ...
- Jmeter(十五) - 从入门到精通 - JMeter导入自定义的Jar包(详解教程)
1.简介 原计划这一篇是介绍前置处理器的基础知识的,结果由于许多小伙伴或者童鞋们在微信和博客园的短消息中留言问如何引入自己定义的Jar包呢???我一一回复告诉他们和引入插件的Jar包一样的道理,一通百 ...
- PE文件格式详解(五)
0x00 前言 前一篇了解了区块虚拟地址和文件地址转换的相关知识,这一篇该把我们所学拿出来用用了.这篇我们将了解更为重要的一个知识点——输入表和输出表的知识. 0x01 输入表 首先我们有疑问.这个输 ...
- 线下---复习day02
目录 1 后续课程安排 2 作业讲解 3 python中的魔法方法 setattr,getattr,setitem,getitem演示 with 上下文管理器 eq 4 cookie,session, ...