DEV Community

Interface gráfica com Powershell

Já criamos scripts de backup simples, com funções, com uma forma de acessibilidade, mas será que conseguimos também sair do terminal e deixar ele com uma cara mais de "programa"?

Com o Powershell podemos criar uma interface gráfica simples, e inegavelmente com uma cara antiga, para os scripts.
É um processo bem trabalhoso mas pode ser útil, então vale a pena compartilhar.

Vou tentar pelo texto explicar um pouco da ideia geral do que vamos fazer e compartilhar um script super comentado para exemplificar.

Precisamos ter algumas noção para criar essa interface, a primeira delas é que criaremos um formulário, então vamos pensar que temos uma folha em branco onde precisamos desenhar o que queremos mostrar.

Para esse exemplo, precisamos desenhar:

  1. Campos de texto não interativos
  2. Botões que estão sempre visíveis
  3. Um botão que só vai aparecer quando uma condição for cumprida

Para localizar as pastas, vamos escrever uma função para exibir para o usuário o Windows Explorer e permitir que ele visualmente selecione a pasta que quer salvar e onde quer salvar.

Para fazer a magica acontecer, vamos interagir com um evento do botão, nesse caso o momento em que o usuário clica nele. Trabalhando com esse evento, deixamos de gatilho para que o trecho do código seja executado somente quando o usuário utilizar.

Esse script é realmente mais complicado de explicar, mas com o exemplo, acredito que consiga replicar e modificar.

# Funcao para pegar a pasta
Function Localizar-Pasta {
try {
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$OpenFileDialog = New-Object System.Windows.Forms.FolderBrowserDialog
$OpenFileDialog.ShowDialog() | Out-Null
$caminhoPasta = $OpenFileDialog.SelectedPath
return $caminhoPasta
}
catch {
$ErrorMessage = $_.Exception.Message # Recebe o erro
Write-Host $ErrorMessage # Exibe a mensagem de erro
}
}
# Faz o backup
function Fazer-Backup {
param (
[parameter(position=0, Mandatory=$True)]
$origem,
[parameter(position=1, Mandatory=$True)]
$destino
)
# Faz a copia
try {
Copy-Item "$origem\*" -Destination "$destino" -Recurse -Force # Copia o arquivo
$retorno = "Procedimento concluido"
}
catch {
$ErrorMessage = $_.Exception.Message # Recebe a mensagem de erro
$retorno = "Erro: $ErrorMessage"
}
# Retorna a resposta da funcao
return $retorno
}
# Interface Grafica:
# Formulario principal
Add-Type -assembly System.Windows.Forms # Recebe a biblioteca
Add-Type -AssemblyName PresentationFramework # Recebe a biblioteca de mensagens
$GUI = New-Object System.Windows.Forms.Form # Cria o formulario principal
$GUI.Text ='Fazer Backup' # Titulo
$GUI.Size = New-Object System.Drawing.Size(320,130) # Define o tamanho
$GUI.StartPosition = 'CenterScreen' # Inicializa no centro da tela
# Pasta de origem
$lblOrigem = New-Object System.Windows.Forms.Label # Cria a label
$lblOrigem.Text = "Pasta origem:" # Define um texto para ela
$lblOrigem.Location = New-Object System.Drawing.Point(0,10) # Define em qual coordenada da tela vai ser desenhado
$lblOrigem.AutoSize = $true # Configura tamanho automatico
$GUI.Controls.Add($lblOrigem) # Adiciona ao formulario principal
# Botao para escolher o diretorio
$btnOrigem = New-Object System.Windows.Forms.Button # Cria um botao
$btnOrigem.Location = New-Object System.Drawing.Size(100,10) # Define em qual coordenada da tela vai ser desenhado
$btnOrigem.Size = New-Object System.Drawing.Size(200,18) # Define o tamanho
$btnOrigem.Text = "Definir pasta" # Define o texto
$GUI.Controls.Add($btnOrigem) # Adiciona ao formulario principal
# Pasta de destino
$lblDestino = New-Object System.Windows.Forms.Label # Cria a label
$lblDestino.Text = "Pasta destino:" # Define um texto para ela
$lblDestino.Location = New-Object System.Drawing.Point(0,30) # Define em qual coordenada da tela vai ser desenhado
$lblDestino.AutoSize = $true # Configura tamanho automatico
$GUI.Controls.Add($lblDestino) # Adiciona ao formulario principal
# Botao para escolher o diretorio
$btnDestino = New-Object System.Windows.Forms.Button # Cria um botao
$btnDestino.Location = New-Object System.Drawing.Size(100,30) # Define em qual coordenada da tela vai ser desenhado
$btnDestino.Size = New-Object System.Drawing.Size(200,18) # Define o tamanho
$btnDestino.Text = "Definir pasta" # Define o texto
$GUI.Controls.Add($btnDestino) # Adiciona ao formulario principal
# Botao para fazer o procedimento
$btnFazerBackup = New-Object System.Windows.Forms.Button # Cria um botao
$btnFazerBackup.Location = New-Object System.Drawing.Size(5,50) # Define em qual coordenada da tela vai ser desenhado
$btnFazerBackup.Visible = $false # Deixa desativado
$btnFazerBackup.Size = New-Object System.Drawing.Size(300,25) # Define o tamanho
$btnFazerBackup.Text = "Fazer Backup" # Define o texto
$GUI.Controls.Add($btnFazerBackup) # Adiciona ao formulario principal
# Label para salvar dados
$ProdOrigem = New-Object System.Windows.Forms.Label # Cria a label
$ProdOrigem.Text = "" # Coloca um texto em branco
$ProdOrigem.Visible = $false # Deixa invisivel na inicializacao
$ProdOrigem.Location = New-Object System.Drawing.Point(0,15) # Define em qual coordenada da tela vai ser desenhado
$ProdOrigem.AutoSize = $true # Configura tamanho automatico
$GUI.Controls.Add($ProdOrigem) # Adiciona ao formulario principal
$ProdDestino = New-Object System.Windows.Forms.Label # Cria a label
$ProdDestino.Text = "" # Coloca um texto em branco
$ProdDestino.Visible = $false # Deixa invisivel na inicializacao
$ProdDestino.Location = New-Object System.Drawing.Point(0,15) # Define em qual coordenada da tela vai ser desenhado
$ProdDestino.AutoSize = $true # Configura tamanho automatico
$GUI.Controls.Add($ProdDestino) # Adiciona ao formulario principal
# Label para receber o retorno do procedimento
$lblRetorno = New-Object System.Windows.Forms.Label # Cria a label
$lblRetorno.Text = "" # Coloca um texto em branco
$lblRetorno.Location = New-Object System.Drawing.Point(0,50) # Define em qual coordenada da tela vai ser desenhado
$lblRetorno.AutoSize = $true # Configura tamanho automatico
$GUI.Controls.Add($lblRetorno) # Adiciona ao formulario principal
# Evento do Botao Diretorio de origem
$btnOrigem.Add_Click({
$caminhoPasta = Localizar-Pasta # Recebe a pasta
$ProdOrigem.Text = $caminhoPasta # Salva caminho selecionado
$lblRetorno.Text = "Selecione uma pasta destino"
})
# Evento do Botao Diretorio de destino
$btnDestino.Add_Click({
$caminhoPasta = Localizar-Pasta # Recebe a pasta
$ProdDestino.Text = $caminhoPasta # Salva caminho selecionado
$btnFazerBackup.Visible = $true # Ativa o botão
})
# Evento do Botao de backup
$btnFazerBackup.Add_Click({
# Recebe os dados
$lblRetorno.Text = "Fazendo a copia..."
$origem = $ProdOrigem.Text
$destino = $ProdDestino.Text
# Faz o procedimento e exibe
$retono = Fazer-Backup $origem $destino
$lblRetorno.Text = "$retono"
# Limpa as caixas
$btnFazerBackup.Visible = $false
$ProdOrigem.Text = ""
$ProdDestino.Text = ""
})
# Inicia o formulario
$GUI.ShowDialog() # Desenha na tela todos os componentes adicionados ao formulario
view raw BackupGUI.ps1 hosted with ❤ by GitHub

Precisamos apontar exatamente a posição do que queremos desenhar, o que pode dificultar um pouco o processo de deixar a interface bonita e com uma boa usabilidade.
Um outro ponto de atenção importante, se encerrar o terminal a interface também é fechada.

Concluindo, acho valido comentar que não é só porque conseguimos fazer, que devemos fazer. Powershell é uma linguagem muito útil para automatizar sistemas, mas nem por isso precisamos fazer tudo com ela.
Uma interface gráfica feita por uma linguagem de programação mais "convencional", provavelmente terá um desempenho, usabilidade e aparência melhores do que vamos conseguir nesse script.
E claro, podemos manter nossa logia de manipulação de sistema feita por scripts e aciona-los nessa interface.

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay