WOW安装文件能不能丈夫不和自己睡一起运行程序放一起?

除了***WOW客户端的那个8G的文件夹,其他的文件有关WOW的一些文件删了是不是不影响WOW运行_百度知道1 if (IntPtr.Size == 4) 2 return eArchitecture.x86; 3 else if 4 (IntPtr.Size == 8) 5 return eArchitecture.x64;
System.IntPtr被设计用来保存内存地址的。在.NET中,它提供了一个非常方便的属性告诉我们它的长度。因此,如果它的长度是8个字节,我们就是在用64位地址。如果是4字节,我们就在32位环境中。就是如此简单!
注意:如果你的组件编译时选择X86为目标平台,运行它的进程永远都是32位。即使运行在64位环境中,它使用的是WOW64模式(模拟32位),并且仍然是32位进程
Windows 64位基础结构(Windows 64-bit infrastructure)
如上所述,Windows 64位操作系统提供了WOW64模式来允许运行X86应用程序。微软的工程师们决定不在你的硬盘上混淆32位和64位应用程序,所有X64应用程序被***到默认的"Program Files"文件夹下面,同时,X86应用程序被***到新的"Program Files(X86)"文件夹下面。
Windows X64注册表
在X64的Windows操作系统中,WOW64模式为32位应用程序和64位应用程序提供了分开的注册表逻辑视图(logical view),这让应用程序像访问两个独立的注册表。当为X64平台开发或者部署应用程序时,这是需要考虑的重要一点,因为X86-targeted的***工程会以不同的方式访问注册表。简单来说,它用以下的方式工作:
Windows截获来自应用程序和组件对于注册表的调用,并且重定向到相应的注册表逻辑视图。这个过程对应用程序是透明的。可以从了解到注册表重定向的更多信息。
尽管下面的命名方式不是百分百正确,我们仍然分别称这两个注册表逻辑视图为32位注册表和64位注册表。
使用Visual Studio***工程部署应用程序(Deploy Application with Visual Studio Setup Projects)
和很多人一样,如果你也是使用Visual Studio***工程和Windows ***包来部署你的应用程序,并且你想让你的应用程序同时兼容"X86"和"X64"平台,这里有一组你需要考虑的事情。
Visual Studio工程的目标平台
就像一般的组件一样,***工程也有目标平台属性,当你在工程浏览器(Solution Explorer)中选中***工程时,你可以在属性页中看到这个属性。如下图所示:
不幸的是这里没有"Any CPU"选项,所以我们必须自己选择平台。这个平台选择会影响到下面的几个方面:
你应用程序的默认***目录:"Program Files" 或者"Program Files (X86)"。
如果***工程需要修改注册表,这个会影响到***程序是更新64位注册表还是WOW64进程中重定向的32位注册表。如果你的***工程用到注册表,这是一个重要的事情。
所以,我应该给***工程选择怎样的目标平台呢?它依赖于你的应用程序怎样被编译的和怎样为运行在X64环境下做准备。具体如下:
如果你的应用程序编译成X86平台相关的,选择X86作为***工程的目标平台。
如果你的应用程序编译成X64平台相关的,选择X64作为***工程的目标平台。
如果你的应用程序使用"Any CPU"编译:
如果你的应用程序已经为运行在X64环境下准备好了(例如,注册表访问已经考虑到WOW64模式),选择X64
如果你不能确信你的应用程序已经为X64环境准备好了,选择X86
那我的注册表键值在哪里呢?如上所述,如果你的***工作使用X86作为目标平台,它就不会修改64位注册表,而是重定向到由WOW64模式提供的32位注册表。因此,当你正常打开"regedit.exe"时,并不能找到它们。取而代之的是你需要打开这个特别的RegEdit去显示32位注册表:[Windows Installation path]\SysWOW64\regedit.exe
从C#访问注册表(Acessing the rigistry from C#)
你已经理解了Windows X64基础架构怎样设计的,以及你的应用程序怎样被***工程***的。现在,你可能需要学习怎样处理Window X64中两个注册表视图(Windows 64位注册表和Windows 32位注册表)。尤其是当你的应用程序以X86编译的并运行在WOW64模式下时。
常见的.NET访问注册表方式
想象你现在需要访问"LOCAL_MACHINE\Software"注册表节点下面的某个键。在.NET中,一般用下面的代码来做这件事情(使用名字空间Microsoft.Win32):
1 RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\[Your Key Here]");
这种做法在Windows X64机器中将只能访问到"64位"注册表,即使你的进程是运行在WOW64模式下面。因此,如果你的应用程序是用X86***工程***的,我们上面要找的注册表项就会找不到(因为***包目标平台是X86,所有的注册表项***时都写到"32位"注册表中)。我们真正需要访问的是由WOW64提供的"32位"注册表。
从C#访问32位WOW64注册表
到目前为止,.NET平台还没有方法让我们直接访问WOW64模式下面的32位注册表。为了实现这个功能,我们必须要使用Windows自身的API调用,导入"advapi32.dll"并使用函数。这个函数有一个参数"samDesired",它是用来指定访问选项的标识组合,其中一个选项(KEY_WOW64_32KEY)就是指定我们希望打开的注册表视图是WOW64下的32位注册表。
samDesired中的标识
ValueMeaning
KEY_ALL_ACCESS (0xF003F)
Combines the STANDARD_RIGHTS_REQUIRED, KEY_QUERY_VALUE, KEY_SET_VALUE, KEY_CREATE_SUB_KEY, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, and KEY_CREATE_LINK access rights.
KEY_CREATE_LINK (0x0020)
Reserved for system use.
KEY_CREATE_SUB_KEY (0x0004)
Required to create a subkey of a registry key.
KEY_ENUMERATE_SUB_KEYS (0x0008)
Required to enumerate the subkeys of a registry key.
KEY_EXECUTE (0x20019)
Equivalent to KEY_READ.
KEY_NOTIFY (0x0010)
Required to request change notifications for a registry key or for subkeys of a registry key.
KEY_QUERY_VALUE (0x0001)
Required to query the values of a registry key.
KEY_READ (0x20019)
Combines the STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY values.
KEY_SET_VALUE (0x0002)
Required to create, delete, or set a registry value.
KEY_WOW64_32KEY (0x0200)
Indicates that an application on 64-bit Windows should operate on the 32-bit registry view. For more information, see .
This flag must be combined using the OR operator with the other flags in this table that either query or access registry values.
Windows 2000: This flag is not supported.
KEY_WOW64_64KEY (0x0100)
Indicates that an application on 64-bit Windows should operate on the 64-bit registry view. For more information, see .
This flag must be combined using the OR operator with the other flags in this table that either query or access registry values.
Windows 2000: This flag is not supported.
KEY_WRITE (0x20006)
Combines the STANDARD_RIGHTS_WRITE, KEY_SET_VALUE, and KEY_CREATE_SUB_KEY access rights.
1 [DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegOpenKeyEx")]
2 static extern int RegOpenKeyEx(IntPtr hKey, string subKey, uint options, int sam,
3 out IntPtr phkResult);
6 public enum eRegWow64Options : int
8 None = 0x0000,
9 KEY_WOW64_64KEY = 0x0100, 10 KEY_WOW64_32KEY = 0x0200, 11 // Add here any others needed, from the table of the previous chapter 12 } 13 14 [Flags] 15 public enum eRegistryRights : int 16 { 17 ReadKey = 131097, 18 WriteKey = 131078, 19 } 20 21 public static RegistryKey OpenSubKey(RegistryKey pParentKey, string pSubKeyName, 22 bool pWriteable, 23 eRegWow64Options pOptions) 24 { 25 if (pParentKey == null || GetRegistryKeyHandle(pParentKey).Equals(System.IntPtr.Zero)) 26 throw new System.Exception("OpenSubKey: Parent key is not open"); 27 28 eRegistryRights Rights = eRegistryRights.ReadK 29 if (pWriteable) 30 Rights = eRegistryRights.WriteK 31 32 System.IntPtr SubKeyH 33 System.Int32 Result = RegOpenKeyEx(GetRegistryKeyHandle(pParentKey), pSubKeyName, 0, 34 (int)Rights | (int)pOptions, out SubKeyHandle); 35 if (Result != 0) 36 { 37 ponentModel.Win32Exception W32ex = 38 new ponentModel.Win32Exception(); 39 throw new System.Exception("OpenSubKey: Exception encountered opening key", 40 W32ex); 41 } 42 43 return PointerToRegistryKey(SubKeyHandle, pWriteable, false); 44 } 45 46 private static System.IntPtr GetRegistryKeyHandle(RegistryKey pRegisteryKey) 47 { 48 Type Type = Type.GetType("Microsoft.Win32.RegistryKey"); 49 FieldInfo Info = Type.GetField("hkey", BindingFlags.NonPublic | BindingFlags.Instance); 50 51 SafeHandle Handle = (SafeHandle)Info.GetValue(pRegisteryKey); 52 IntPtr RealHandle = Handle.DangerousGetHandle(); 53 54 return Handle.DangerousGetHandle(); 55 } 56 57 private static RegistryKey PointerToRegistryKey(IntPtr hKey, bool pWritable, 58 bool pOwnsHandle) 59 { 60 // Create a SafeHandles.SafeRegistryHandle from this pointer - this is a private class 61 BindingFlags privateConstructors = BindingFlags.Instance | BindingFlags.NonP 62 Type safeRegistryHandleType = typeof( 63 SafeHandleZeroOrMinusOneIsInvalid).Assembly.GetType( 64 "Microsoft.Win32.SafeHandles.SafeRegistryHandle"); 65 66 Type[] safeRegistryHandleConstructorTypes = new Type[] { typeof(System.IntPtr), 67 typeof(System.Boolean) }; 68 ConstructorInfo safeRegistryHandleConstructor = 69 safeRegistryHandleType.GetConstructor(privateConstructors, 70 null, safeRegistryHandleConstructorTypes, null); 71 Object safeHandle = safeRegistryHandleConstructor.Invoke(new Object[] { hKey, 72 pOwnsHandle }); 73 74 // Create a new Registry key using the private constructor using the 75 // safeHandle - this should then behave like 76 // a .NET natively opened handle and disposed of correctly 77 Type registryKeyType = typeof(Microsoft.Win32.RegistryKey); 78 Type[] registryKeyConstructorTypes = new Type[] { safeRegistryHandleType, 79 typeof(Boolean) }; 80 ConstructorInfo registryKeyConstructor = 81 registryKeyType.GetConstructor(privateConstructors, null, 82 registryKeyConstructorTypes, null); 83 RegistryKey result = (RegistryKey)registryKeyConstructor.Invoke(new Object[] { 84 safeHandle, pWritable }); 85 return 86 }87 88
"OpenSubKey"函数将会返回搜索的注册表项,它允许你指定从正常的注册表中读取还是从WOW64模式下的32位注册表中读取。下面的例子就是从WOW64模式下的32位注册表中读取注册表项:
3 RegistryKey key = OpenSubKey(Registry.LocalMachine,"Software\\[Key]",false,
4 eRegWow64Options.KEY_WOW64_32KEY);
8 // Parent key not open, exception found at opening (probably related to
9 // security permissions requested) 10 }
你只需要把上面代码中的"[Key]"替换成你想要搜索的注册表项即可。
怎样让你的应用程序是注册表读取安全的(How to make your application a bulletproof registry reader)
现在,你已经有方法读取X64环境下的两个注册表了,我建议你用下面的方式来处理注册表访问问题
首先,使用.NET中的标准方式"Registry.LocalMachine.OpenSubKey"查找注册表项。这个方式能够覆盖你的程序运行在32位Windows上和运行在64位Windows上非WOW64模式的情况。
如果注册表项没有找到,用下面方式中的一种进行处理:
检测Windows版本
32位:异常,注册表没有找到
64位:尝试使用上面的代码去访问WOW64模式下的注册表。如果同样没有找到,启动异常处理
直接尝试去访问WOW64模式下的注册表,但把这段代码放到"try-catch"语句内。如果捕获到异常,或者注册表项没有找到,启动异常处理后使用快捷导航没有帐号?
查看: 466|回复: 9
魂丶饮血双刃
Lv.5, 积分 1402, 距离下一级还需 1098 积分
UID3857594帖子威望0 多玩草52 草
这两天有点蛋疼,想回国服看看,我电脑里已经安好台服了,在***国服的时候发现提示直接运行台服,国服客户端不能***,请问怎么解决呢?
注:我把两个客户端的***文件都放在一个硬盘里,是两个独立文件夹,不会是他们互相产生影响吧。
新人欢迎积分1 阅读权限1积分10389精华0UID2824676帖子金钱5724 威望-3
头像被屏蔽
我要维护世界和平!!
UID2824676帖子威望-3 多玩草113 草
一个放D盘,一个放E盘试试
新人欢迎积分1 阅读权限60积分2799精华0UID1133566帖子金钱3156 威望0
Lv.6, 积分 2799, 距离下一级还需 2201 积分
UID1133566帖子威望0 多玩草26 草
***好一个后,文件夹复制到其他地方,然后卸载,把wow.exe改名,继续***另外一个。
新人欢迎积分0 阅读权限80积分18503精华0UID1175749帖子金钱26645 威望0
Lv.8, 积分 18503, 距离下一级还需 1497 积分
UID1175749帖子威望0 多玩草136 草
硬盘里面3个wow客户端,,,没觉得有虾米问题啊
魂丶饮血双刃
Lv.5, 积分 1402, 距离下一级还需 1098 积分
UID3857594帖子威望0 多玩草52 草
额,试过了,失败,目前采取从新解压来试试看。
请问还有那位朋友有高招,主要是不想删除台服客户端,***补丁很麻烦,我把两个客户端都放在移动硬盘里
慢慢改变……
新人欢迎积分-2 阅读权限50积分2207精华0UID5773486帖子金钱3080 威望1
Lv.5, 积分 2207, 距离下一级还需 293 积分
UID5773486帖子威望1 多玩草148 草
一个放D盘,一个放E盘
玩国服的时候把台服客户端的文件夹名改了
玩台服的时候把国服客户端的文件夹名改了
Lv.7, 积分 9623, 距离下一级还需 377 积分
UID4374591帖子威望9 多玩草163 草
台服装在硬盘,国服装在移动硬盘,台服提示更新的时候砍掉移动硬盘连接,国服提示更新的时候.......你认为国服会比台服版本更先进?So...程序会自动识别的....
An KaranirThanagor&&Mor Ok Angalor&&Mor Ok GorumPalahm&&Raval
哥在莫要狂
Lv.5, 积分 1219, 距离下一级还需 1281 积分
UID7155218帖子威望0 多玩草23 草
分开放& &文件夹名字不要一样&&
魔兽世界 台服
魔兽世界 国服
魔兽世界WLK 单机版& &
文件夹名字不一样就行了~~~~
当亲友团遇上六亲不认...
大领主提里奥佛丁:小泰兰,爹要出征杀天灾了
血色领主泰兰佛丁:父亲,让我和你一起出征吧
大领主提里奥佛丁:板甲满
_______________________
玛法里奥?怒风:弟弟,我要去安其拉杀虫子了
伊利丹?怒风 :哥哥,让我和你一起去吧
玛法里奥?怒风 :皮甲不分
魂丶饮血双刃
Lv.5, 积分 1402, 距离下一级还需 1098 积分
UID3857594帖子威望0 多玩草52 草
谢谢朋友们支招,万分感谢。
新人欢迎积分0 阅读权限40积分292精华0UID1683456帖子金钱35 威望0
Lv.4, 积分 292, 距离下一级还需 708 积分
UID1683456帖子威望0 多玩草10 草
用不同的window用户***。
大众尚酷(Scirocco)0/1
元宝专属一阶勋章。已绝版
需要金钱:1100
Powered by
手机盒子客户端点击或扫描下载

参考资料

 

随机推荐