如果我的应用程序检测到未设置别名,则在运行时需要设置一个SQL别名。现在,我让它生成一个临时Reg文件并通过regedit.exe运行它,但是因为我的应用程序是32位的(一定是因为我正在与一些32位dll互操作,但我无法获得64位版本)当我运行regedit到版本%windir%\SysWow64\regedit.exe而不是%windir%\regedit.exe时,正在执行重定向。

这导致我尝试写入[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo]的键被重定向到32位子文件夹,而我的显式写入32位子文件夹[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\MSSQLServer\Client\ConnectTo]我不知道它们的去向。

通常,要解决此问题,您只需使用%windir%\sysnative\xxxx.exe,但sysnative重定向到System32文件夹而不是regedit所在的根Windows文件夹。

有没有一种方法可以解决此问题,而无需编写自定义程序来进行抬高并自己完成?



这是我当前的代码,失败了。

static void CreateAliases()
{
    using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
    {
        using (var key = baseKey.OpenSubKey(@"SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo"))
        {
            CheckKeys(key);
        }
    }
    try
    {
        using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
        {
            using (var key = baseKey.OpenSubKey(@"SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo"))
            {
                CheckKeys(key);
            }
        }
    }
    catch
    {
        //Catch failues if it is 32 bit only.
    }
}

private static void CheckKeys(RegistryKey key)
{
    //check to see if the key exists.
    if (key == null)
    {
        AddKeys();
        return;
    }

    var value = key.GetValue(@"wi\sql2008");
    if (value == null || value.ToString() != String.Concat("DBMSSOCN,wi,", Properties.Settings.Default.wi_sql2008Port))
    {
        AddKeys();
        return;
    }

    value = key.GetValue(@"wi\sql2005");
    if (value == null || value.ToString() != String.Concat("DBMSSOCN,wi,", Properties.Settings.Default.wi_sql2005Port))
    {
        AddKeys();
        return;
    }
}
static private void AddKeys()
{

    string file = System.IO.Path.GetTempFileName();
    using(StreamWriter sw = new StreamWriter(file))
    {
        sw.WriteLine("Windows Registry Editor Version 5.00");
        sw.WriteLine();
        sw.WriteLine(@"[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\MSSQLServer\Client\ConnectTo]");
        sw.WriteLine(String.Concat("\"wi\\\\sql2005\"=\"DBMSSOCN,wi,", Properties.Settings.Default.wi_sql2005Port,'"'));
        sw.WriteLine(String.Concat("\"wi\\\\sql2008\"=\"DBMSSOCN,wi,", Properties.Settings.Default.wi_sql2008Port,'"'));
        sw.WriteLine();
        sw.WriteLine(@"[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo]");
        sw.WriteLine(String.Concat("\"wi\\\\sql2005\"=\"DBMSSOCN,wi,", Properties.Settings.Default.wi_sql2005Port, '"'));
        sw.WriteLine(String.Concat("\"wi\\\\sql2008\"=\"DBMSSOCN,wi,", Properties.Settings.Default.wi_sql2008Port, '"'));
    }

    WindowsIdentity identity = WindowsIdentity.GetCurrent();
    WindowsPrincipal principal = new WindowsPrincipal(identity);
    bool IsAdmin = principal.IsInRole("BUILTIN\\Administrators");

    string regedit;

    if (Environment.Is64BitProcess)
    {
        regedit = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "regedit");
    }
    else
    {
        regedit = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "sysnative", "regedit"); //regedit.exe does not exist in sysnative.
    }

    if (IsAdmin)
    {
        var proc = Process.Start(new ProcessStartInfo(regedit, String.Concat("/s ", file)));
        proc.WaitForExit();
    }
    else
    {
        MessageBox.Show("Updating registry keys for WI alias, this must be run as administrator");
        var proc = Process.Start(new ProcessStartInfo(regedit, String.Concat("/s ", file)) { Verb = "runas", UseShellExecute = true });
        proc.WaitForExit();
    }

    File.Delete(file);

}


这是正在生成的临时文件。

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\MSSQLServer\Client\ConnectTo]
"wi\\sql2005"="DBMSSOCN,wi,49224"
"wi\\sql2008"="DBMSSOCN,wi,49681"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo]
"wi\\sql2005"="DBMSSOCN,wi,49224"
"wi\\sql2008"="DBMSSOCN,wi,49681"

最佳答案

我会考虑使用SMO ServerAlias class创建服务器别名,那么您不必自己处理注册表访问。

09-26 21:23