André Alves de Lima

Talking about Software Development and more…

Listando as instâncias do SQL Server com C# e VB.NET

Um dos artigos mais acessados até hoje aqui no site é aquele onde eu mostrei como podemos fazer backup e restauração do SQL Server através do C#. Esses dias atrás, recebi um e-mail de alguém que tinha lido esse artigo perguntando como ele poderia verificar se uma instância do SQL Server já estava instalada e rodando (por exemplo, uma instância chamada “SQLEXPRESS“). Pensei comigo: “Hmm, que dúvida interessante, ainda não sei como fazer isso“. Resolvi pesquisar e acabei descobrindo que conseguimos listar facilmente as instâncias do SQL Server com C# e VB.NET através do SMO (que é a mesma biblioteca que utilizamos para fazer o backup e restauração). Vamos ver como podemos implementar essa funcionalidade na nossa aplicação?

Criando o projeto de exemplo

Para entendermos como é que funciona o processo de listagem das instâncias do SQL Server, vamos criar um novo projeto do tipo “Windows Forms Application“. Não se engane: o código que eu vou mostrar nesse artigo funciona nas outras plataformas também (como WPF, ASP.NET, Console Application, etc). Só escolhi Windows Forms para facilitar a nossa vida.

Uma vez criado o projeto, vamos adicionar as referências às bibliotecas do SMO (SQL Server Management Objects). Você encontra esses itens dentro da categoria “Extensions” da tela “Reference Manager“:

– Microsoft.SqlServer.ConnectionInfo
– Microsoft.SqlServer.Management.Sdk.Sfc
– Microsoft.SqlServer.Smo
– Microsoft.SqlServer.SmoExtended

Em seguida, vamos ajustar o formulário do nosso projeto, adicionando um DataGridView (dataGridViewInstancias) e um botão (listarSQLButton), de forma que ele fique parecido com a imagem a seguir:

Listando todas as instâncias (rede e local)

Agora que já temos o formulário criado e as referências do SMO adicionadas ao projeto, vamos implementar o código para listarmos todas as instâncias que conseguirmos encontrar, tanto na rede quanto no computador local. Isso é muito tranquilo de ser feito com o SMO, mais especificamente com a classe SmoApplication. Essa classe possui um método estático (chamado EnumAvailableSqlServers) que implementa justamente a funcionalidade de listar as instâncias do SQL Server.

O método “EnumAvailableSqlServers” possui três sobrecargas. A primeira delas não recebe nenhum parâmetro, e o resultado da sua chamada será uma DataTable contendo as informações de todas as instâncias que forem encontradas, tanto na rede quanto no computador onde a aplicação está sendo executada. O código do evento de clique no nosso botão deve ficar assim:

        // C#
        private void listarSQLButton_Click(object sender, EventArgs e)
        {
            dataGridViewInstancias.DataSource = Microsoft.SqlServer.Management.Smo.SmoApplication.EnumAvailableSqlServers();
        }
    ' VB.NET
    Private Sub listarSQLButton_Click(sender As Object, e As EventArgs) Handles listarSQLButton.Click
        dataGridViewInstancias.DataSource = Microsoft.SqlServer.Management.Smo.SmoApplication.EnumAvailableSqlServers()
    End Sub

Execute a aplicação, clique no botão e veja o resultado:

Filtrando a pesquisa pelo nome da instância

Em algumas situações, pode ser que precisemos procurar por um nome de instância específico. Nesse caso, ao invés de simplesmente chamarmos o método “EnumAvailableSqlServers” e filtrarmos o resultado, podemos utilizar a sobrecarga do método que recebe uma string, que é justamente o filtro que queremos utilizar na busca.

Vamos, então, adicionar um TextBox no formulário (nomeInstanciaTextBox), onde o usuário poderá especificar o nome do servidor e instância que ele quer procurar:

Em seguida, vamos fazer uma pequena alteração no código para considerarmos esse TextBox na consulta:

        // C#
        private void listarSQLButton_Click(object sender, EventArgs e)
        {
            DataTable servers = null;
            if (!string.IsNullOrWhiteSpace(nomeInstanciaTextBox.Text))
                servers = Microsoft.SqlServer.Management.Smo.SmoApplication.EnumAvailableSqlServers(nomeInstanciaTextBox.Text);
            else
                servers = Microsoft.SqlServer.Management.Smo.SmoApplication.EnumAvailableSqlServers();
            dataGridViewInstancias.DataSource = servers;
        }
    ' VB.NET
    Private Sub listarSQLButton_Click(sender As Object, e As EventArgs) Handles listarSQLButton.Click
        Dim servers As DataTable = Nothing
        If Not String.IsNullOrWhiteSpace(nomeInstanciaTextBox.Text) Then
            servers = Microsoft.SqlServer.Management.Smo.SmoApplication.EnumAvailableSqlServers(nomeInstanciaTextBox.Text)
        Else
            servers = Microsoft.SqlServer.Management.Smo.SmoApplication.EnumAvailableSqlServers()
        End If
        dataGridViewInstancias.DataSource = servers
    End Sub

Pronto! Agora podemos procurar por uma instância específica do SQL Server:

Pesquisando somente instâncias locais

Uma outra opção que podemos adicionar no nosso formulário é alternativa de pesquisarmos somente as instâncias locais. A terceira sobrecarga do método “EnumAvailableSqlServers” recebe um parâmetro booleano. Quando passamos “true” para esse parâmetro, o método fará a pesquisa somente no computador onde a aplicação está rodando (e não na rede toda).

Para implementarmos essa opção, vamos adicionar um CheckBox no nosso formulário (somenteInstanciasLocaisCheckBox):

E, no código, utilizamos a informação da propriedade “Checked” no parâmetro do método “EnumAvailableSqlServers“:

        // C#
        private void listarSQLButton_Click(object sender, EventArgs e)
        {
            DataTable servers = null;
            if (!string.IsNullOrWhiteSpace(nomeInstanciaTextBox.Text))
                servers = Microsoft.SqlServer.Management.Smo.SmoApplication.EnumAvailableSqlServers(nomeInstanciaTextBox.Text);
            else
                servers = Microsoft.SqlServer.Management.Smo.SmoApplication.EnumAvailableSqlServers(somenteInstanciasLocaisCheckBox.Checked);
            dataGridViewInstancias.DataSource = servers;
        }
    ' VB.NET
    Private Sub listarSQLButton_Click(sender As Object, e As EventArgs) Handles listarSQLButton.Click
        Dim servers As DataTable = Nothing
        If Not String.IsNullOrWhiteSpace(nomeInstanciaTextBox.Text) Then
            servers = Microsoft.SqlServer.Management.Smo.SmoApplication.EnumAvailableSqlServers(nomeInstanciaTextBox.Text)
        Else
            servers = Microsoft.SqlServer.Management.Smo.SmoApplication.EnumAvailableSqlServers(somenteInstanciasLocaisCheckBox.Checked)
        End If
        dataGridViewInstancias.DataSource = servers
    End Sub

Feito isso, ao pesquisarmos as instâncias com o CheckBox marcado, somente as instâncias locais serão retornadas (no meu caso, não tenho nenhuma instância local instalada, por isso a lista está vazia):

Concluindo

As classes disponíveis no pacote SQL Server Management Object possuem funcionalidades muito interessantes para gerenciarmos bancos de dados SQL Server. Uns tempos atrás eu mostrei como criar e restaurar backups do SQL Server utilizando essas classes. Hoje eu resolvi mostrar como podemos utilizar essas mesmas classes para pesquisarmos instâncias do SQL Server com C# e VB.NET.

Você já teve a necessidade de saber se uma instância do SQL Server estava disponível ou não? Se sim, como é que você acabou resolvendo essa necessidade? Utilizando as classes do SMO, como eu demonstrei nesse artigo, ou de alguma outra forma? Conte-nos mais detalhes na caixa de comentários!

Por fim, convido você a inscrever-se na minha newsletter. Ao fazer isso, você receberá um e-mail toda semana sobre o artigo publicado e ficará sabendo também em primeira mão sobre o artigo da próxima semana, além de receber dicas “bônus” que eu só compartilho por e-mail. Inscreva-se utilizando o formulário logo abaixo.

Até a próxima!

André Lima

Newsletter do André Lima

* indicates required



Powered by MailChimp

16 thoughts on “Listando as instâncias do SQL Server com C# e VB.NET

  • Paulo Almeida disse:

    André,

    Como sempre, artigos exclentes, oportunos e extremamente úteis.

    Mais uma vez, obrigado.

  • Robson Matos disse:

    Muito interessante Andre, esse Exemplo.

  • André, obrigada por mais esse post. Como sempre, valiosos para nós desenvolvedores.

    • andrealveslima disse:

      Olá Alessandra, muito obrigado pelo comentário! Fico feliz que você tenha achado o conteúdo desse artigo valioso!

      Um grande abraço!
      André Lima

  • Alex A Furlan disse:

    Olá Andre.
    Parece até que voce advinha o que nós estamos precisando. Seu artigo caiu como uma luva. Muitíssimo obrigado pelo seu trabalho comunitário.

    • andrealveslima disse:

      Olá Alex, obrigado pelo comentário!

      Cara, que legal que você estava precisando dessa funcionalidade! É muito bom quando conseguimos produzir um conteúdo que “casa” com as necessidades dos leitores.. :)

      Abraço!
      André Lima

  • Edward Gómez disse:

    Buen día André,

    Excelente articulo, al igual que bases de datos de copia de seguridad y restauración de SQL Server para C #, me ha sido de mucha utilidad.

    Un abrazo.

    Saludos desde Colombia.

  • Lázaro disse:

    Otimo artigo ..
    Agora faça um exemplo de como listar bancos da instancia selecionada

  • Eduardo Henrique de Paula disse:

    Meu caro,

    Estou pensando em uma aplicação, que por definição utilizará duas plataformas (desktop/mobile).

    O sistema local (desktop) deverá funcionar em tempo integral, independentemente da internet, pois quando estiver sem conexão, o mesmo terá apenas a inibição de determinadas funções que necessitem de consistências, rodando em um status OFF LINE.

    Devida a esta característica, penso em espelhar (duplicar) a instalação do banco de dados (SQLServer local e servidor).

    O sistema desktop será desenvolvido no Visual Studio em C# .net;

    Exemplificando:
    A – Quando a internet NÃO estiver conectada, algumas funções deverão ficar inibidas, pois não existirá a possibilidade de consistência, tipo:
    A1 – No caso do cadastro de um novo cliente verificar se o mesmo já está cadastrado (INIBIDA);
    A2 – Efetuar um lançamento no contas a pagar (desde que a conta, o fornecedor, o centro de custo, etc. estejam cadastrados) (LIBERADA);
    A3 – assim que a conexão for restabelecida, o servidor deverá ser atualizado.

    B – Quando a internet estiver conectada, todas as funções ficam liberadas, possibilitando a gravação local e no servidor de dados(isto é claro, kkk).

    A minha intenção com este modelo de aplicação será de nunca não parar totalmente o meu cliente.

    Gostaria de sua opinião sobre a viabilidade deste projeto, se já existe alguma ferramenta que resolva este meu problema de gravação (local e servidor), ou qual seria a sua dica para eu montar o processo acima.

    Desde já te agradeço.

    • andrealveslima disse:

      Olá Eduardo!

      Esse tipo de implementação pode ser feita sim, sem problema nenhum.. O único problema é que ela não é tão trivial assim.. Aqui na empresa onde eu trabalho nós criamos uma funcionalidade desse tipo em que a comunicação é feita através de web services.. No servidor temos alguns web services que ficam ouvindo o cliente offline e sincronizando os novos dados de tempos em tempos (15 em 15 minutos)..

      Como você vai ter um cliente desktop e mobile, não vai ter outra saída a não ser partir para utilização de web services para comunicar-se com a base.. Você poderia criar uma API REST (com ASP.NET Web API, por exemplo) e fazer toda a persistência de dados através dela.. Essa API seria utilizada tanto para a aplicação desktop quanto para a aplicação mobile.. Na aplicação desktop, você poderia a qualquer momento verificar se a API está acessível (ou seja, se você tem acesso a internet e se o servidor está acessível) para habilitar ou desabilitar funções..

      Concluindo: é possível de ser realizado sem problema algum.. Mas, dá um certo trabalho.. :)

      Abraço!
      André Lima

  • Eduardo disse:

    Caro Andre Lima,

    Muito obrigado pela sua atenção e rapidez na resposta, com certeza me ajudou muito e vou me aprofundar nas dicas que você passou.

    • andrealveslima disse:

      Magina, Eduardo! Qualquer dúvida ou dificuldade na implementação, é só entrar em contato.. Se eu souber a resposta, eu ajudo sem problema nenhum.. :)

      Sucesso aí nos projetos! Abraço!
      André Lima

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *