Windows 注册表问题
Windows Registry Issue
我正在尝试使用 D 修改注册表中的一些值,但它一直给我以下错误:
Value cannot be set
但是,如果我用 C# 编写完全相同的代码,那么它就可以工作。是D中注册表模块的问题还是我使用方式的问题?
D
module main;
import std.windows.registry;
import std.stdio;
import core.thread;
void main() {
string languageName = "English";
string languageCode = "en_uk";
const uint languageValue = 0x00000001;
writefln("Name '%s' Code '%s' Value '%s'", languageName, languageCode, languageValue);
writeln("Press ENTER to change language.");
readln();
writefln("Changing language of Sims 2 to '%s' ...", languageName);
Thread.sleep(dur!("msecs")(2000));
string keyName;
try {
enum versions = [
"",
"Apartment Life",
"Bon Voyage",
"Celebration Stuff",
"Family Fun Stuff",
"Free Time",
"Fun with Pets Collection",
"Glamour Life Stuff",
"H M Fashion Stuff",
"IKEA Home Stuff",
"Kitchen & Bath Interior Design Stuff",
"Mansion and Garden Stuff",
"Nightlife",
"Open For Business",
"Pets",
"Seasons",
"Teen Style Stuff",
"University"
];
foreach (simsVersion; versions) {
keyName = "SOFTWARE\Wow6432Node\EA GAMES\The Sims 2";
if (simsVersion && simsVersion.length)
keyName ~= " " ~ simsVersion;
// main
{
scope auto key = Registry.localMachine.getKey(keyName);
key.setValue("Language", languageName);
key.setValue("Locale", languageCode);
key.flush();
}
// sub
{
keyName ~= "\1.0";
scope auto key = Registry.localMachine.getKey(keyName);
key.setValue("Language", languageValue);
key.setValue("LanguageName", languageName);
key.flush();
}
writefln("Changed language of '%s' ...", simsVersion);
}
writeln("Success...");
Thread.sleep(dur!("msecs")(2000));
}
catch (Throwable t) {
writefln("Key Entry: '%s'", keyName);
writeln(t);
readln();
}
}
C#
class Program
{
public static void Main(string[] args)
{
const string languageName = "English";
const string languageCode = "en_uk";
const uint languageValue = 0x00000001;
string[] versions = new string[]
{
"",
"Apartment Life",
"Bon Voyage",
"Celebration Stuff",
"Family Fun Stuff",
"FreeTime",
"Fun with Pets Collection",
"Glamour Life Stuff",
"H M Fashion Stuff",
"IKEA Home Stuff",
"Kitchen & Bath Interior Design Stuff",
"Mansion and Garden Stuff",
"Nightlife",
"Open For Business",
"Pets",
"Seasons",
"Teen Style Stuff",
"University"
};
const string mainKey = @"SOFTWARE\Wow6432Node\EA GAMES\The Sims 2";
string keyName = "";
try
{
Console.WriteLine("Name '{0}' Code '{1}' Value '{2}'", languageName, languageCode, languageValue);
Console.WriteLine("Press ENTER to change language.");
Console.ReadLine();
Console.WriteLine("Changing language of Sims 2 to '{0}' ...", languageName);
Thread.Sleep(2000);
foreach (var simsVersion in versions)
{
if (!string.IsNullOrWhiteSpace(simsVersion))
keyName = mainKey + " " + simsVersion;
else
keyName = mainKey;
// main
{
var key = Registry.LocalMachine.OpenSubKey(keyName, true);
key.SetValue("Language", languageName);
key.SetValue("Locale", languageCode);
key.Close();
}
// sub
{
keyName += "\1.0";
var key = Registry.LocalMachine.OpenSubKey(keyName, true);
key.SetValue("Language", languageValue);
key.SetValue("LanguageName", languageName);
key.Close();
}
Console.WriteLine("Changed language of '{0}' ...", simsVersion);
}
Console.WriteLine("Success...");
Thread.Sleep(2000);
}
catch (Exception e)
{
Console.WriteLine("Key: '{0}'", keyName);
Console.WriteLine(e);
Console.ReadLine();
}
}
}
因为您有 SOFTWARE\WOW6432Node
注册表项,所以您的系统是 64 位的。默认情况下,C# 编译器(请参阅 /platform:anycpu,它在 VS 中也默认使用)生成一个程序集,该程序集 运行 在 64 位系统上作为 64 位进程,在 32- 系统上作为 32 位进程位系统。
此外,默认情况下,64 位系统上的 32 位进程的注册表查询被重定向到特殊的 WOW6432Node
子项(例如,请求打开 HKLM\Software
实际上会打开 HKLM\Software\WOW6432Node
,参见 MSND article "32-bit and 64-bit Application Data in the Registry")。结果,您的 32 位 D 应用程序(就像如果 运行 作为 32 位进程,您的 C# 应用程序将执行的操作)实际上尝试打开 SOFTWARE\Wow6432Node\Wow6432Node\EA GAMES\The Sims 2
不存在的密钥。
要解决此问题,请在 64 位模式下编译 D 应用程序(-m64
开关)或使用 REGSAM.KEY_WOW64_64KEY
禁用默认重定向:
Registry.localMachine.getKey(keyName, REGSAM.KEY_READ | REGSAM.KEY_WOW64_64KEY);
注意:RegistryView.Registry64 可用于禁用 C# 中的默认重定向,如果它 运行 在 64 位系统上作为 32 位进程。
我正在尝试使用 D 修改注册表中的一些值,但它一直给我以下错误:
Value cannot be set
但是,如果我用 C# 编写完全相同的代码,那么它就可以工作。是D中注册表模块的问题还是我使用方式的问题?
D
module main;
import std.windows.registry;
import std.stdio;
import core.thread;
void main() {
string languageName = "English";
string languageCode = "en_uk";
const uint languageValue = 0x00000001;
writefln("Name '%s' Code '%s' Value '%s'", languageName, languageCode, languageValue);
writeln("Press ENTER to change language.");
readln();
writefln("Changing language of Sims 2 to '%s' ...", languageName);
Thread.sleep(dur!("msecs")(2000));
string keyName;
try {
enum versions = [
"",
"Apartment Life",
"Bon Voyage",
"Celebration Stuff",
"Family Fun Stuff",
"Free Time",
"Fun with Pets Collection",
"Glamour Life Stuff",
"H M Fashion Stuff",
"IKEA Home Stuff",
"Kitchen & Bath Interior Design Stuff",
"Mansion and Garden Stuff",
"Nightlife",
"Open For Business",
"Pets",
"Seasons",
"Teen Style Stuff",
"University"
];
foreach (simsVersion; versions) {
keyName = "SOFTWARE\Wow6432Node\EA GAMES\The Sims 2";
if (simsVersion && simsVersion.length)
keyName ~= " " ~ simsVersion;
// main
{
scope auto key = Registry.localMachine.getKey(keyName);
key.setValue("Language", languageName);
key.setValue("Locale", languageCode);
key.flush();
}
// sub
{
keyName ~= "\1.0";
scope auto key = Registry.localMachine.getKey(keyName);
key.setValue("Language", languageValue);
key.setValue("LanguageName", languageName);
key.flush();
}
writefln("Changed language of '%s' ...", simsVersion);
}
writeln("Success...");
Thread.sleep(dur!("msecs")(2000));
}
catch (Throwable t) {
writefln("Key Entry: '%s'", keyName);
writeln(t);
readln();
}
}
C#
class Program
{
public static void Main(string[] args)
{
const string languageName = "English";
const string languageCode = "en_uk";
const uint languageValue = 0x00000001;
string[] versions = new string[]
{
"",
"Apartment Life",
"Bon Voyage",
"Celebration Stuff",
"Family Fun Stuff",
"FreeTime",
"Fun with Pets Collection",
"Glamour Life Stuff",
"H M Fashion Stuff",
"IKEA Home Stuff",
"Kitchen & Bath Interior Design Stuff",
"Mansion and Garden Stuff",
"Nightlife",
"Open For Business",
"Pets",
"Seasons",
"Teen Style Stuff",
"University"
};
const string mainKey = @"SOFTWARE\Wow6432Node\EA GAMES\The Sims 2";
string keyName = "";
try
{
Console.WriteLine("Name '{0}' Code '{1}' Value '{2}'", languageName, languageCode, languageValue);
Console.WriteLine("Press ENTER to change language.");
Console.ReadLine();
Console.WriteLine("Changing language of Sims 2 to '{0}' ...", languageName);
Thread.Sleep(2000);
foreach (var simsVersion in versions)
{
if (!string.IsNullOrWhiteSpace(simsVersion))
keyName = mainKey + " " + simsVersion;
else
keyName = mainKey;
// main
{
var key = Registry.LocalMachine.OpenSubKey(keyName, true);
key.SetValue("Language", languageName);
key.SetValue("Locale", languageCode);
key.Close();
}
// sub
{
keyName += "\1.0";
var key = Registry.LocalMachine.OpenSubKey(keyName, true);
key.SetValue("Language", languageValue);
key.SetValue("LanguageName", languageName);
key.Close();
}
Console.WriteLine("Changed language of '{0}' ...", simsVersion);
}
Console.WriteLine("Success...");
Thread.Sleep(2000);
}
catch (Exception e)
{
Console.WriteLine("Key: '{0}'", keyName);
Console.WriteLine(e);
Console.ReadLine();
}
}
}
因为您有 SOFTWARE\WOW6432Node
注册表项,所以您的系统是 64 位的。默认情况下,C# 编译器(请参阅 /platform:anycpu,它在 VS 中也默认使用)生成一个程序集,该程序集 运行 在 64 位系统上作为 64 位进程,在 32- 系统上作为 32 位进程位系统。
此外,默认情况下,64 位系统上的 32 位进程的注册表查询被重定向到特殊的 WOW6432Node
子项(例如,请求打开 HKLM\Software
实际上会打开 HKLM\Software\WOW6432Node
,参见 MSND article "32-bit and 64-bit Application Data in the Registry")。结果,您的 32 位 D 应用程序(就像如果 运行 作为 32 位进程,您的 C# 应用程序将执行的操作)实际上尝试打开 SOFTWARE\Wow6432Node\Wow6432Node\EA GAMES\The Sims 2
不存在的密钥。
要解决此问题,请在 64 位模式下编译 D 应用程序(-m64
开关)或使用 REGSAM.KEY_WOW64_64KEY
禁用默认重定向:
Registry.localMachine.getKey(keyName, REGSAM.KEY_READ | REGSAM.KEY_WOW64_64KEY);
注意:RegistryView.Registry64 可用于禁用 C# 中的默认重定向,如果它 运行 在 64 位系统上作为 32 位进程。