64 位 Windows 平台开发注意要点之文件系统重定向
Program Files 的重定向
很多开发人员都知道,在 64 位 Windows 系统上,32 位程序是无法获取得到 C:\Program Files 的完整路径的,只能获取到 C:\Program Files (x86)。不管你用的是什么方法:
TCHAR szPath[MAX_PATH] = { 0 };
ExpandEnvironmentStrings(_T("%ProgramFiles%"), szPath, MAX_PATH);又或者是:
SHGetSpecialFolderPath(NULL, szPath, CSIDL_PROGRAM_FILES, FALSE);
SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, szPath);
这个问题在 Windows NT 6.0 (Windows Vista) 之前的系统上无解,只有 64 程序可以拿到这个路径。Windows NT 6.0 开始,微软对此进行了重新设计,以前称作「Special Folders」(特殊文件夹)的系统文件夹有了一个全新的名字,叫「Known Folders」(已知文件夹),同时提供了一套新的接口,包括 Windows API 函数 SHGetKnownFolderPath,COM 接口 IKnownFolder 和 IKnownFolderManager 来管理这些系统文件夹,原来的 CSIDL(Constant Special Item ID list)系列整数值也被一套新的「KNOWNFOLDERID」系列 GUID 所代替,可以获取得到的文件夹数量比以前也更多,而且随着 Windows 的版本越来越高,可获取的文件夹路径也越来越多。如,程序可以直接通过 FOLDERID_QuickLaunch 获取 Quick Launch(快速启动),以及通过 FOLDERID_LocalAppDataLow 获取 LocalLow 等路径。不过,经测试,32 位程序使用下面的代码仍然无法获取到 C:\Program Files。
PWSTR pszPath = NULL;
HRESULT hr = SHGetKnownFolderPath(FOLDERID_ProgramFilesX64, 0, NULL, &pszPath);
if (hr == S_OK)
{
CoTaskMemFree((void *)pszPath);
}在 64 位系统上,上面的代码编译为 32 位程序,结果依然是失败。多年来,经过多次不懈的搜索,终于找到 32 位程序在 64 位系统上获取 C:\Program Files 的方法:
TCHAR szPath[MAX_PATH] = { 0 };
ExpandEnvironmentStrings(_T("%ProgramW6432%"), szPath, MAX_PATH);虽然说这个环境变量并无法在批处理和命令行中使用。个人猜测,这个环境变量仅在 64 位系统上的 32 位程序中有效。而 64 位系统的 cmd 也是 64 位,自然批处理中无法使用环境变量。经测试,Windows XP x64 Edition 也能通过这个方法得到该路径。
System32 的重定向
System32 重定向和 Program Files 不同的是,System32 的重定向是底层实现的,即 32 位程序显式的指定向 System32 文件夹写入,实际还是写入到 SysWOW64。而 32 位程序在拥有权限的情况下,向 Program Files 写入并不会被重定向到 Program Files (x86)。向 System32 和 Program Files 两个文件夹中写入数据的相同点是都需要管理员权限,否则无法写入。System32 的重定向是可以通过以下的 API 来更改:
PVOID lpOldValue = NULL;
if (Wow64DisableWow64FsRedirection(&lpOldValue))
{
// 调用 CreateFile、_open、fopen 等
Wow64RevertWow64FsRedirection(lpOldValue);
}
64 位 Windows 平台开发注意要点之文件系统重定向的更多相关文章
- 64 位 Windows 平台开发注意要点之注册表重定向
Window 系统错误代码 ERROR_SUCCESS,本博客中一律使用 NO_ERROR 代替.虽然 ERROR_SUCCESS 与 NO_ERROR 是完全等价的,都代表成功,但是后者却和其他错误 ...
- 64位WINDOWS系统环境下应用软件开发的兼容性问题(CPU 注册表 目录)
应用软件开发的64 位WINDOWS 系统环境兼容性 1. 64 位CPU 硬件 目前的64位CPU分为两类:x64和IA64.x64的全称是x86-64,从名字上也可以看出来它和 x86是兼容的,原 ...
- 64位 Windows 用了 32位编译平台 编译不过 MySQL API
发生在一周前的事情了,当时想感受下 MySQL C API ,就写了几个小例子.虽然是在 Windows(我的工作电脑是 64位 Windows) 上面,但是不想用 VS ,只想用文本软件写好代码后用 ...
- [百度空间] [转]将程序移植到64位Windows
from : http://goooder.bokee.com/2000373.html (雷立辉 整理) 简介:本文对如何将32位Windows程序平滑的支持和过渡到64位Windows操作系统做出 ...
- 【转载】64 位 Windows 内核虚拟地址空间布局(基于 X64 CPU)
原文链接:http://shayi1983.blog.51cto.com/4681835/1734822 本文为原创翻译,原文出处为 http://www.codemachine.com/articl ...
- Winio驱动在64位windows下无法使用的解决方法
C#在使用WinIo的驱动开发类似按键精灵一类工具的时候,需要对相关的驱动进行注册才能正常启动,找了下资料,资料来自: http://jingyan.baidu.com/article/642c9d3 ...
- 解决Tomcat6解压版在64位windows系统上无法启动服务的问题
解决Tomcat6解压版在64位windows系统上无法启动服务的问题 由于客户环境为64位windows系统,开发环境一直用32位.tomcat使用6.0.20非安装版.部署时发现在 ...
- 【扫盲】】32位和64位Windows的区别
用户购买windows安装盘或者重新安装操作系统的时候,通常会遇到这个问题,就是不知道该如何选择使用32位操作系统和64位操作系统,有人说64位系统速度快,其实理论上确实是这样,不过具体还要根据你的个 ...
- 64位windows上访问64位oracle 12c
64位windows上访问64位oracle 12c,这会有啥问题? 没啥问题.问题是,我64位操作系统的机器上装了个oracle 10g.而oracle 10g好像是不区分啥32位.64位的,一律3 ...
随机推荐
- QEMU模拟器Windows版本模拟ARMX86CPU指令
http://qemu.weilnetz.de/ QEMU Binaries for Windows
- 3.14 unittest之skip
3.14 unittest之skip 前言当测试用例写完后,有些模块有改动时候,会影响到部分用例的执行,这个时候我们希望暂时跳过这些用例.或者前面某个功能运行失败了,后面的几个用例是依赖于这个功能的用 ...
- java.lang.NullPointerException错误的解决方案
java.lang.NullPointerException空指针异常是像我一样新手很容易出现的问题,这个问题一般情况都是不细心的时候出现的,开始正文如下: 1.业务层面的错误: a.没有写非空验证: ...
- Mathematica求微分换元
[转载请注明出处]http://www.cnblogs.com/mashiqi 2017/12/16 有时我们需要对PDEs中的各项进行变量替换,比如把$\frac{\text{d}}{\text{d ...
- HQL知识点一
Hive创表语法 create [external] table [if not exists] [db_name.]table_name (col1_name data_type,col2_name ...
- appium-doctor问题
在电脑上安装Appium,打开CDM运行appium-doctor,运行报错提示如下 检查运营Java.javac.java -version均有返回值,说明我的配置是成功,输入where Java, ...
- Spock - Document -05 - Extensions
Extensions Peter Niederwieser, The Spock Framework TeamVersion 1.1 Spock comes with a powerful exten ...
- DEV gridview根据单元格值改变其他单元格格式
string style = ""; private void gridView1_RowCellStyle(object sender, DevExpress.XtraGrid. ...
- java项目---遍历系统文件(1星)
package Demo; import java.io.*; public class TraversalContent { public static void main(String []arg ...
- Python的内置方法
一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object) ...