我使用.NET 4和新的RegistryKey.FromHandle調用,因此我可以從打開a軟件註冊表文件RegLoadAppKey,並使用現有的託管API對其進行操作。RegLoadAppKey在32位操作系統上工作正常,在64位操作系統上失敗,即使這兩個進程都是32位
我剛開始認爲這只是一個搗亂的DllImport問題,我的調用在參數或缺少的MarshalAs或其他類型中有一個無效類型,但是查看其他註冊表函數和它們的DllImport聲明(例如,在pinvoke .net),我沒有看到還有什麼可以嘗試的(我有hKey作爲int和IntPtr返回,都在32位操作系統上運行,並在64位操作系統上失敗)
我懂了儘可能簡單地記錄一個重複案例 - 它只是試圖創建一個「隨機」子項,然後爲其寫入一個值。它在我的Win7 x86機器上運行良好,並且在Win7 x64和2008 R2 x64上失敗,即使它仍然是32位進程,甚至可以從32位cmd提示符運行。編輯:如果它是一個64位進程,它也會以同樣的方式失敗。 編輯:它工作正常,如果文件傳入是空的 - 問題情況是現有的軟件註冊表配置單元。我從2008 r2(x64)和WHS v1(x86)iso提取'裸'軟件註冊表配置單元文件,兩者都有相同的問題。
Win7上的x86:
INFO: Running as Admin in 32-bit process on 32-bit OS
Was able to create Microsoft\Windows\CurrentVersion\RunOnceEx\a95b1bbf-7a04-4707-bcca-6aee6afbfab7 and write a value under it
上Win7的X64,作爲32位:
INFO: Running as Admin in 32-bit process on 64-bit OS
Unhandled Exception: System.UnauthorizedAccessException: Access to the registry key '\Microsoft\Windows\CurrentVersion\RunOnceEx\ce6d5ff6-c3af-47f7-b3dc-c5a1b9a3cd22' is denied.
at Microsoft.Win32.RegistryKey.Win32Error(Int32 errorCode, String str)
at Microsoft.Win32.RegistryKey.CreateSubKeyInternal(String subkey, RegistryKeyPermissionCheck permissionCheck, Object registrySecurityObj, RegistryOptions registryOptions)
at Microsoft.Win32.RegistryKey.CreateSubKey(String subkey)
at LoadAppKeyAndModify.Program.Main(String[] args)
上Win7的X64,爲64位:
INFO: Running as Admin in 64-bit process on 64-bit OS
Unhandled Exception: System.UnauthorizedAccessException: Access to the registry key '\Microsoft\Windows\CurrentVersion\RunOnceEx\43bc857d-7d07-499c-8070-574d6732c130' is denied.
at Microsoft.Win32.RegistryKey.Win32Error(Int32 errorCode, String str)
at Microsoft.Win32.RegistryKey.CreateSubKeyInternal(String subkey, RegistryKeyPermissionCheck permissionCheck, Object registrySecurityObj, RegistryOptions registryOptions)
at Microsoft.Win32.RegistryKey.CreateSubKey(String subkey, RegistryKeyPermissionCheck permissionCheck)
at LoadAppKeyAndModify.Program.Main(String[] args)
源:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("INFO: Running as {0} in {1}-bit process on {2}-bit OS",
new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator) ? "Admin" : "Normal User",
Environment.Is64BitProcess ? 64 : 32,
Environment.Is64BitOperatingSystem ? 64 : 32);
if (args.Length != 1)
{
throw new ApplicationException("Need 1 argument - path to the software hive file on disk");
}
string softwareHiveFile = Path.GetFullPath(args[0]);
if (File.Exists(softwareHiveFile) == false)
{
throw new ApplicationException("Specified file does not exist: " + softwareHiveFile);
}
// pick a random subkey so it doesn't already exist
var existingKeyPath = @"Microsoft\Windows\CurrentVersion";
var keyPathToCreate = @"RunOnceEx\" + Guid.NewGuid();
var completeKeyPath = Path.Combine(existingKeyPath, keyPathToCreate);
var hKey = RegistryNativeMethods.RegLoadAppKey(softwareHiveFile);
using (var safeRegistryHandle = new SafeRegistryHandle(new IntPtr(hKey), true))
using (var appKey = RegistryKey.FromHandle(safeRegistryHandle))
using (var currentVersionKey = appKey.OpenSubKey(existingKeyPath, true))
{
if (currentVersionKey == null)
{
throw new ApplicationException("Specified file is not a well-formed software registry hive: " + softwareHiveFile);
}
using (var randomSubKey = currentVersionKey.CreateSubKey(keyPathToCreate))
{
randomSubKey.SetValue("foo", "bar");
Console.WriteLine("Was able to create {0} and write a value under it", completeKeyPath);
}
}
}
}
internal static class RegistryNativeMethods
{
[Flags]
public enum RegSAM
{
AllAccess = 0x000f003f
}
private const int REG_PROCESS_APPKEY = 0x00000001;
// approximated from pinvoke.net's RegLoadKey and RegOpenKey
// NOTE: changed return from long to int so we could do Win32Exception on it
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int RegLoadAppKey(String hiveFile, out int hKey, RegSAM samDesired, int options, int reserved);
public static int RegLoadAppKey(String hiveFile)
{
int hKey;
int rc = RegLoadAppKey(hiveFile, out hKey, RegSAM.AllAccess, REG_PROCESS_APPKEY, 0);
if (rc != 0)
{
throw new Win32Exception(rc, "Failed during RegLoadAppKey of file " + hiveFile);
}
return hKey;
}
}
不,當你運行它的64位機器上的64位進程工作的呢? – luke 2010-05-27 03:16:57
很好的問題,不,它不是 – 2010-05-27 04:29:45