2015-05-07 13 views
6

Próbuję modyfikować pewne wartości w rejestrze przy użyciu D, ale to wciąż daje mi następujący błąd:Windows Registry Issue

Value cannot be set

Jednak jeśli piszę dokładnie ten sam kod w C# to działa. Czy jest to problem z modułem rejestru w D lub czy jest to problem ze sposobem, w jaki go używam?

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

Czy Twój kod D jest skompilowany jako 64-bitowy? –

+0

Czy używasz również programu jako administrator? –

+0

Kompiluję się z 32-bitową wersją i działam jako administrator. – Bauss

Odpowiedz

1

Jak masz SOFTWARE\WOW6432Node wpis rejestru system jest 64-bitowy. Domyślnie kompilator C# (zobacz /platform:anycpu, jest również używany domyślnie w VS) tworzy zespół, który działa jako proces 64-bitowy w systemie 64-bitowym i jako proces 32-bitowy w systemie 32-bitowym.

Również domyślnie rejestru zapytań w procesie 32-bitowego na 64-bitowym systemie są przekierowywane do specjalnego WOW6432Node podklucz (na przykład żądanie, aby otworzyć HKLM\Software będzie faktycznie otwarte HKLM\Software\WOW6432Node patrz MSND article "32-bit and 64-bit Application Data in the Registry"). W rezultacie twoja 32-bitowa aplikacja D (podobnie jak twoja aplikacja C# zrobi, jeśli będzie działać jako proces 32-bitowy) faktycznie spróbuje otworzyć klucz SOFTWARE\Wow6432Node\Wow6432Node\EA GAMES\The Sims 2, który nie istnieje.

Aby rozwiązać ten problem, albo skompilować aplikację D w trybie 64-bitowym (-m64 switch) lub użyć REGSAM.KEY_WOW64_64KEY wyłączyć domyślną przekierowanie:

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

Uwaga: RegistryView.Registry64 mogą być wykorzystane, aby wyłączyć domyślne przekierowanie w języku C# jeśli to działa jako proces 32-bitowy w systemie 64-bitowym.