【问题标题】:Create SQL Server Alias Using WMI on x64在 x64 上使用 WMI 创建 SQL Server 别名
【发布时间】:2010-08-16 00:32:15
【问题描述】:

我有一个小应用程序,它会自动为某些服务器创建必要的 SQL Server 别名条目。大部分代码如下所示:

        private static void SetAlias(string aliasName, string server, string protocol, int? port)
        {
            var scope = new ManagementScope(@"\\.\root\Microsoft\SqlServer\ComputerManagement10");
            try
            {
                scope.Connect();

            }
            catch
            {
                scope = new ManagementScope(@"\\.\root\Microsoft\SqlServer\ComputerManagement");
            }
            var clientAlias = new ManagementClass(scope, new ManagementPath("SqlServerAlias"), null);
            clientAlias.Get();

            foreach (ManagementObject existingAlias in clientAlias.GetInstances())
            {
                existingAlias.Get();
                if (String.Equals((String)existingAlias.GetPropertyValue("AliasName"), aliasName))
                {
                    UpdateAlias(existingAlias, aliasName, server, protocol, port);
                    return;
                }
            }

            // create new
            ManagementObject newAlias = clientAlias.CreateInstance();
            UpdateAlias(newAlias, aliasName, server, protocol, port);
            newAlias.Put();
        }

        private static void UpdateAlias(ManagementObject alias, string aliasName, string server, string protocol, int? port)
        {
            alias.SetPropertyValue("AliasName", aliasName);
            alias.SetPropertyValue("ServerName", server);
            alias.SetPropertyValue("ProtocolName", protocol);
            alias.SetPropertyValue("ConnectionString", port != null ? port.ToString() : string.Empty);
        }

这会在 32 位操作系统上正确创建我想要的条目,但是在 x64 操作系统上,我还需要将别名添加到 64 位 SQL Server 客户端配置中。

任何想法如何做到这一点?

谢谢。

【问题讨论】:

    标签: c# sql-server wmi system.management


    【解决方案1】:

    我将保留注册表答案,因为它是可行的,但您可以使用 ConnectionOptions 上的上下文来指定拱门(一个 int、32 或 64)

    从 64 位访问两者的示例:

        static void Main(string[] args)
        {
            var options = new ConnectionOptions();
    
            if (Environment.Is64BitOperatingSystem && Environment.Is64BitProcess == false)
            {
                Console.WriteLine("Please build as AnyCPU or x64");
                return;
            }
    
            // default behavior, should be 64-bit WMI provider
            Console.WriteLine("Print 64-bit aliases");
            PrintAliases(options);
    
            // specify the 32-bit arch
            Console.WriteLine("Print 32-bit aliases");
            options.Context.Add("__ProviderArchitecture", 32);
            PrintAliases(options);
        }
    
        private static void PrintAliases(ConnectionOptions options)
        {
            var scope = new ManagementScope(@"\\.\root\Microsoft\SqlServer\ComputerManagement10", options);
            try
            {
                scope.Connect();
            }
            catch
            {
                scope = new ManagementScope(@"\\.\root\Microsoft\SqlServer\ComputerManagement");
            }
            var clientAlias = new ManagementClass(scope, new ManagementPath("SqlServerAlias"), null);
            clientAlias.Get();
    
            foreach (ManagementObject existingAlias in clientAlias.GetInstances())
            {
                existingAlias.Get();
                var propertiesToRead = new[] { "AliasName", "ServerName", "ProtocolName", "ConnectionString" };
                foreach (var propertyToRead  in propertiesToRead)
                {
                    Console.WriteLine("Property {0} = {1}", propertyToRead, existingAlias.GetPropertyValue(propertyToRead));
                }
            }
        }
    

    从 32 位访问两者的示例(注意:当然,无论进程位数如何,都可以将拱门强制为 32 和 64)

    class Program
    {
        static void Main(string[] args)
        {
            var options = new ConnectionOptions();
    
            if (Environment.Is64BitProcess)
            {
                Console.WriteLine("Please run this sample as 32-bit");
                return;
            }
    
            // default behavior, should be 32-bit WMI provider since we build as x86
            Console.WriteLine("Print 32-bit aliases");
            PrintAliases(options);
    
            // also prints 32-bit aliases
            options.Context.Add("__ProviderArchitecture", 32);
            PrintAliases(options);
    
            // specify the 64-bit arch
            if (Environment.Is64BitOperatingSystem)
            {
                Console.WriteLine("Print 64-bit aliases");
                options.Context.Add("__ProviderArchitecture", 64);
                PrintAliases(options);
            }
        }
    
        private static void PrintAliases(ConnectionOptions options)
        {
            var scope = new ManagementScope(@"\\.\root\Microsoft\SqlServer\ComputerManagement10", options);
            try
            {
                scope.Connect();
            }
            catch
            {
                scope = new ManagementScope(@"\\.\root\Microsoft\SqlServer\ComputerManagement");
            }
            var clientAlias = new ManagementClass(scope, new ManagementPath("SqlServerAlias"), null);
            clientAlias.Get();
    
            foreach (ManagementObject existingAlias in clientAlias.GetInstances())
            {
                existingAlias.Get();
                var propertiesToRead = new[] { "AliasName", "ServerName", "ProtocolName", "ConnectionString" };
                foreach (var propertyToRead  in propertiesToRead)
                {
                    Console.WriteLine("Property {0} = {1}", propertyToRead, existingAlias.GetPropertyValue(propertyToRead));
                }
            }
        }
    

    【讨论】:

      【解决方案2】:

      当我上次查看时,客户端别名只是保留在注册表中 (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo),因此最简单的方法是写入两个 WoW (HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node \Microsoft\MSSQLServer\Client\ConnectTo) 和在 x64 上运行时的“正常”位置。请注意,如果您作为 32 位进程运行,则在编写 64 位版本时,您需要 p/invoke 或(如果在 .net 4 上)指定 64 位视图。

      【讨论】:

      • 谢谢。我想我确实可以直接点击注册表......如果我不能让它与 WMI 一起使用,我会这样做,但我仍然对如何使用 WMI 感到好奇。
      • 我所知道的 WMI 的唯一方法是运行相同的代码两次,一次在 32 位进程中,一次在 64 位进程中(当然,在 x64 上运行时)。签入 powershell 似乎可以确认。
      • 啊,看起来你可以做到 - 你需要作为 64 位进程运行(所以我建议将你的平台目标更改为 AnyCPU,因为默认是 x86,我m 假设这就是您以 32 位运行的原因)但您可以从 64 位访问 32 位 WMI 提供程序:msdn.microsoft.com/en-us/library/aa393067(VS.85).aspx
      猜你喜欢
      • 2012-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多