9 11 2016
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
Utilizando o Oracle com C# e VB.NET Como imprimir um formulário no Windows Forms com C# e VB.NET?
André,
Como sempre, artigos exclentes, oportunos e extremamente úteis.
Mais uma vez, obrigado.
Olá Paulo, muito obrigado pelo comentário! E obrigado por acompanhar as postagens! :)
Um grande abraço!
André Lima
Muito interessante Andre, esse Exemplo.
Olá Robson, muito obrigado pelo comentário! Fico feliz que você tenha gostado desse artigo!
Abraço!
André Lima
André, obrigada por mais esse post. Como sempre, valiosos para nós desenvolvedores.
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
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.
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
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.
Olá Edward! Muito obrigado pelo comentário e pelo apoio que você sempre tem dado aqui no site! :)
Um grande abraço!
André Lima
Otimo artigo ..
Agora faça um exemplo de como listar bancos da instancia selecionada
Olá Lázaro, muito obrigado pelo comentário!
Adicionei a sua sugestão aqui na minha lista.. Assim que possível, eu escrevo sobre esse tema..
Porém, não é difícil.. Dá para fazer tanto com uma query direto no banco quando com SMO também.. Veja se estes links te ajudam:
Using SMO for retrieving SQL Server, Database, Table info
Get list of databases from SQL Server
Abraço!
André Lima
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.
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
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.
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