2015-05-07 15 views
6

Tôi đang cố gắng để sửa đổi một số giá trị trong registry bằng D, nhưng nó vẫn không ngừng đem lại cho tôi những lỗi sau:Windows Registry Issue

Value cannot be set

Tuy nhiên, nếu tôi viết mã chính xác tương tự trong C# sau đó nó hoạt động. Nó là một vấn đề với các mô-đun đăng ký trong D hoặc là nó một vấn đề với cách tôi đang sử dụng nó?

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(); 
     } 
    } 
} 
+0

Mã D của bạn có được biên dịch thành 64 bit không? –

+0

Ngoài ra, bạn có đang chạy chương trình với tư cách quản trị viên không? –

+0

Tôi đang biên dịch với 32 bit và chạy với tư cách là quản trị viên. – Bauss

Trả lời

1

Như bạn có SOFTWARE\WOW6432Node entry registry hệ thống của bạn là 64-bit. Theo mặc định trình biên dịch C# (xem /platform:anycpu, nó cũng được sử dụng theo mặc định trong VS) tạo ra một assembly chạy theo quy trình 64-bit trên hệ thống 64-bit và là quá trình 32 bit trên hệ thống 32-bit.

Cũng bởi truy vấn registry mặc định của một quá trình 32-bit trên hệ thống 64-bit được chuyển hướng đến đặc biệt WOW6432Node khóa (ví dụ yêu cầu để mở HKLM\Software sẽ thực sự mở HKLM\Software\WOW6432Node, xem MSND article "32-bit and 64-bit Application Data in the Registry"). Kết quả là ứng dụng D 32-bit của bạn (giống như ứng dụng C# của bạn sẽ thực hiện nếu chạy như quy trình 32-bit) thực sự cố gắng mở khóa SOFTWARE\Wow6432Node\Wow6432Node\EA GAMES\The Sims 2 không tồn tại.

Để khắc phục vấn đề này hoặc biên dịch ứng dụng D trong chế độ 64-bit (-m64 switch) hoặc sử dụng REGSAM.KEY_WOW64_64KEY để vô hiệu hóa chuyển hướng mặc định:

Registry.localMachine.getKey(keyName, REGSAM.KEY_READ | REGSAM.KEY_WOW64_64KEY); 

Lưu ý: RegistryView.Registry64 thể được sử dụng để vô hiệu hóa chuyển hướng mặc định trong C# nếu nó chạy dưới dạng quy trình 32 bit trên hệ thống 64 bit.

Các vấn đề liên quan