Criando um aplicativo desktop em Shiny


Como um frequente usuário do R, em certo momento questionei como criar um aplicativo Shiny executável em desktop, sem a dependência de instalação prévia do R e dos pacotes utilizados. Encontrei dois excelentes artigos que apresentam algumas passibilidades: Deploying Desktop Apps with R e Packaging your Shiny App as an Windows desktop app.

Após algumas tentativas, criei uma “receita de bolo” que funcionou bem para mim. Irei compartilhá-la aqui, sem me preocupar com o motivo de algumas etapas, pois foram bem detalhados nos artigos citados. Este processo foi feito no Windows, mas deve ser semelhante para Linux ou macOS (nunca testei).

1 – Esqueleto

1.1. Criar uma pasta para estruturar o aplicativo:

Não foi fornecido texto alternativo para esta imagem

1.2. Baixar o R Portable e instalar na pasta executavel/:

Não foi fornecido texto alternativo para esta imagem

Permitirá utilizar o R como um “motor” independente, sem a necessidade do usuário possuí-lo instalado no sistema.

Obs: a versão 4.0.0 do R apresentou alguns problemas no Windows. Caso ainda não esteja disponível a versão 4.0.2 do R Portable, baixe a versão anterior (3.6.3).

1.3. Ir em R-Portable/App/R-Portable/etc/Rprofile.site e, ao final do arquivo, colar o código:

.First = function(){
    .libPaths(.Library)
}

Isso forçará o R Portable a usar apenas sua biblioteca local para instalar/carregar pacotes.

1.4. Inicie o R Portable e instale os pacotes utilizados no aplicativo Shiny desenvolvido. No mínimo deve ser instalado o pacote shiny.

Não foi fornecido texto alternativo para esta imagem

1.5. Crie a pasta executavel/shiny/ com o aplicativo Shiny desenvolvido.

Não foi fornecido texto alternativo para esta imagem

A proposta não é ensinar a funcionalidade Shiny, mas sim explicar como transformá-la em um executável. Portanto, em app.R, criei um exemplo simples e sem utilidade. Note que incluí session como um parâmetro na função do servidor, e utilizei este objeto para encerrar corretamente o aplicativo quando sua tela for fechada.

library(shiny)


ui <- fluidPage(
  
  titlePanel("Hello Shiny!"),
  
)


server <- function(input, output, session) {
  
  # FINALIZANDO APLICATIVO
  session$onSessionEnded(function() stopApp())
  
}


shinyApp(ui = ui, server = server)

2 – Criar scripts de inicialização do aplicativo

2.1. Criar o script runShinyApp.R na pasta executavel/ com o seguinte código:

chrome.sys = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe'


if (file.exists(chrome.sys))
  options(browser = chrome.sys)
shiny::runApp('./shiny/app.R', launch.browser=T)

A ideia é verificar se o usuário possui o Google Chrome instalado: se sim, abrir o aplicativo neste navegador e, se não, abri-lo no seu navegador padrão.

Lee Pang sugere que se instale uma versão portátil do Google Chrome, assim como o R Portable, para o caso do usuário não ter um navegador instalado. Entendo não ser necessário, por ser um programa mais comum (e também acho mais legal abrir como uma aba adicional no Chrome).

2.2. Criar o script run.vbs para ser um botão de inicialização do aplicativo. Para tal, abra um bloco de notas e cole o seguinte código:

Rexe           = "R-Portable\App\R-Portable\bin\Rscript.exe"
Ropts          = "--no-save --no-environ --no-init-file --no-restore --no-Rconsole"
RScriptFile    = "runShinyApp.R"
Outfile        = "ShinyApp.log" 
strCommand     = Rexe & " " & Ropts & " " & RScriptFile & " 1> " & Outfile & " 2>&1"

intWindowStyle = 0     ' Hide the window and activate another window.'
bWaitOnReturn  = False ' continue running script after launching R   '

' the following is a Sub call, so no parentheses around arguments'
CreateObject("Wscript.Shell").Run strCommand, intWindowStyle, bWaitOnReturn

Salve o arquivo com o nome rub.vbs na pasta executavel/ para criar um inicializador da aplicação.

2.3. Se todas as etapas até aqui foram feitas corretamente, ao clicar duas vezes em run.vbs, o aplicativo abrirá em uma aba do navegador do Google Chrome.

Não foi fornecido texto alternativo para esta imagem

Obs: O arquivo ShinyApp.txt é criado automaticamente para salvar o log de dados.

3 – Compactar em um executável de instalação

Até o momento conseguimos compartilhar a pasta executavel/ e rodar o aplicativo simplesmente clicando duas vezes em run.vbs.

Essa seção busca embelezar o processo, criando um executável de instalação e um atalho personalizado para o desktop.

3.1. Baixe a ferramenta Inno Setup (não precisa instalar na pasta executavel/).

Obs: Você pode baixar um “módulo de criptografia” separado, se quiser utilizar os recursos de criptografia do Inno Setup.

3.2. Salve uma imagem no formato ICO na pasta executavel/. Utilizarei o ico_hello.ico.

Não foi fornecido texto alternativo para esta imagem

Obs: Sites que convertem PNG em ICO são de fácil acesso, costumo utilizar o Convertio.

3.3. Abra um script no Inno Setup e cole o código abaixo:

#define MyAppName "HELLO"  ; NOME DO APLICATIVO
#define MyAppVersion "1.0"  ; VERSÃO
#define MyAppPublisher "My Company, Inc."   ; COMPANHIA
#define MyAppURL "http://www.example.com/"  ; SITE


[Setup]
; NOTA: O valor de AppId identifica exclusivamente este aplicativo. Não use o mesmo valor AppId em instaladores para outros aplicativos.
; (Para gerar um novo GUID, clique em Ferramentas | Gerar GUID dentro do IDE.)
AppId={{E8C494FB-1AE3-45C6-8B6F-F00649056FF7}


AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName=C:\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes


; Remova o comentário da linha a seguir para executar no modo de instalação não administrativa (instalar apenas para o usuário atual).
;PrivilegesRequired=lowest


; Endereço da pasta que será salvo o instalador
OutputDir=C:\Users\Administrador\Documents\Shiny


; Nome do instalador
OutputBaseFilename=HELLO_INSTALADOR


; Endereço do ICO
SetupIconFile=C:\Users\Administrador\Documents\Shiny\executavel\\ico_hello.ico


Compression=lzma
SolidCompression=yes
PrivilegesRequired=none


; Criptografar Instalador
; Encryption=yes


; Senha, se quiser
Password=12345678    


[Languages]
Name: "brazilianportuguese"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl"


[Files]
; Endereço da pasta que será compactada com \* no final
Source: "C:\Users\Administrador\Documents\Shiny\executavel\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
;  NOTA: Não use "Flags: ignoreversion" em nenhum arquivo de sistema compartilhado


; Criar programa de desinstalação
[Icons]
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"


; Substituir com o nome do aplicativo, o nome do arquivo VBS e do arquivo ICO
[Icons]
Name: "{commondesktop}\HELLO"; Filename: "{app}\run.vbs"; IconFilename: {app}\ico_hello.ico

Segue abaixo como fica a visualização do código acima no Inno Setup. Os comentários (em verde) irão indicar os códigos que deverão se alterados para adaptar a um outro executável de instalação.

Não foi fornecido texto alternativo para esta imagem

Após ajustar o script, o execute.

3.4. Será criado um instalador na pasta indicada pelo script. No meu caso o nomeei de HELLO_INSTALADOR.

Não foi fornecido texto alternativo para esta imagem

Caso não tenha instalado o aplicativo logo após o Inno Setup criar o executável, clique duas vezes para instalar.

Esse executável de instalação poderá ser compartilhado com os usuários.

3.5. Após a instalação, será criado um atalho na sua tela principal que abrirá o aplicativo Shiny automáticamente:

Não foi fornecido texto alternativo para esta imagem

Pronto. Temos um aplicativo disponibilizado a partir de um executável de instalação.

Considerações finais

De nada adianta criar um executável, se o aplicativo Shiny não tiver utilidade. Acho que ninguém irá apresentar para o chefe um “Hello Shiny!”.

Para uma maior aprendizado dessa ferramenta, recomendo a consulta dos seguintes links:

#R #R hashtag#Shiny hashtag#RShiny hashtag#AppShiny hashtag#Desktop hashtag#Innosetup