I am trying to create a shiny desktop app following the instruction of this very nice blog post (http://www.r-bloggers.com/deploying-desktop-apps-with-r/)
So basically I have a folder with the following structure:
App
|__ GoogleChromePortable
|__ App
|__ Data
|__ ...
|__ R Portable
|__ App
|__ Data
|__ ...
|__ shiny
|__ ui.R
|__ server.R
|__ ...
|__ LAUNCH.bat/LAUNCH.vbs
|__ runShinyApp.R
I am creating 2 different version, one with GoogleChromePortable and one without. Both versions are exactly the same apart from the path to Chrome in runShinyApp.R
.
runShinyApp.R
:
# checking if correct library paths are being used (only portable one!)
message('library paths:\n', paste('... ', .libPaths(), sep='', collapse='\n'))
# both chromes work!
chrome.sys = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe'
chrome.portable = file.path(getwd(),
'GoogleChromePortable/App/Chrome-bin/chrome.exe')
launch.browser = function(appUrl, browser.path=chrome.portable) {
message('Browser path: ', browser.path)
shell(sprintf('"%s" --app=%s', browser.path, appUrl))
}
shiny::runApp('./shiny/', launch.browser=launch.browser)
The app is launched through a .bat
or .vbs
file which are basically the same but for the fact that the first leaves a Commander Prompt window open.
LAUNCH.bat
:
SET ROPTS=--no-save --no-environ --no-init-file --no-restore --no-Rconsole
R-Portable\App\R-Portable\bin\Rscript.exe %ROPTS% runShinyApp.R 1> ShinyApp.log 2>&1
LAUNCH.vbs
:
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
Issue:
The issue I am having is appearing in both versions and is the following.
IF I have my normal Chrome launched (NOT the portable version) installed on my system, the shiny app launches without any issues. It opens a new window entirely containing only the shiny app.
However IF I do not have a Chrome session open (default one), neither versions of the shiny seem to work. A window opens but loads forever. Looking at the created logs, I get the following error:
[4092:3596:0621/154834:ERROR:url_pattern_set.cc(240)] Invalid url pattern: chrome://print/*
[4092:3596:0621/154834:ERROR:bluetooth_adapter_win.cc(102)] NOT IMPLEMENTED
Any idea what seems to be the issue here?
I have solved it that way with a few changes to run.vbs and runShinyApp.R.
run.vbs:
Rexe = "R-Portable\App\R-Portable\bin\R.exe CMD BATCH"
Ropts = "--no-save --no-environ --no-init-file --no-restore --no-Rconsole "
RScriptFile = "runShinyApp.R"
Outfile = "ShinyApp.log"
startChrome = "GoogleChromePortable\Chrome\chrome.exe --app=http://127.0.0.1:7777"
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
CreateObject("Wscript.Shell").Run startChrome, intWindowStyle, bWaitOnReturn
I added the startChrome
variable and call CreateObject
after I start the server, because otherwise there is no website and Chrome does not automatically reload when you start it afterwards. Usually starting the server should be fast enough but if you are on a very slow machine it might take too long. Then you need to add a delay between the two CreateObject
calls.
The --app setting opens the app in a window that does not have all the Google Chrome buttons and then it really looks like a standalone app.
runShinyApp.R:
require(shiny)
shiny::runApp('./shiny/',port=7777)
Port 7777 is arbitrary, you can use any free port you like. The port has to be same in all files.
In case you want to use a bat file:
SET ROPTS=--no-save --no-environ --no-init-file --no-restore --no-Rconsole
start /b GoogleChromePortable\Chrome\chrome.exe --app=http://127.0.0.1:7777
R-Portable\App\R-Portable\bin\R.exe CMD BATCH %ROPTS% runShinyApp.R 1> ShinyAppOut.log 2> ShinyAppMsg.log
I moved away from using the portable version of Chrome because of issues like this while developing the RInno package, which is based on Dr. Lee Pang's DesktopDeployR framework. The package helps automate this and incorporates Inno Setup installers so that non-technical users can install and use your Shiny apps.
To get started:
install.packages("RInno")
require(RInno)
RInno::install_inno()
Then you just need to call two functions to create an installation framework:
create_app(app_name = "myapp", app_dir = "path/to/myapp")
compile_iss()
If you would like to include R for your co-workers who don't have it installed, add include_R = TRUE
to create_app
:
create_app(app_name = "myapp", app_dir = "path/to/myapp", include_R = TRUE)
It defaults to include shiny, magrittr and jsonlite, so if you are using other packages like ggplot2 or plotly, just add them to the pkgs
argument. You can also include GitHub packages to the remotes
argument:
create_app(
app_name = "myapp",
app_dir = "path/to/myapp"
pkgs = c("shiny", "jsonlite", "magrittr", "plotly", "ggplot2"),
remotes = c("talgalili/installr", "daattali/shinyjs"))
If you are interested in other features, check out FI Labs - RInno
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With