You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部署在shinyapps.io的Shiny App能否调用客户端Fiji并回传结果?

问题:部署Shiny App到shinyapps.io后,如何调用客户端本地Fiji并回传分析结果?

我搭建了一款本地运行正常的Shiny App,可通过以下代码自动启动ImageJ Fiji应用、执行宏代码分析图像并将结果回传至Shiny App:

Path0 <- "C:/Users/Username/Fiji.app/ImageJ-win64.exe --ij2 --run C:/Users/Username/Fiji.app/macros/TestingShiny.ijm"
system(Path0)

现计划将该App部署至shinyapps.io,让用户无需下载R即可完成全流程分析(预计用户仍需本地安装Fiji)。但部署后,原文件路径与system调用无法正常工作。

简化版测试App代码如下:

## Load Packages
pacman::p_load(pacman, rmarkdown, shiny, shinydashboard, shinyWidgets, fresh, here, tinytex, htmlwidgets)

# Create the theme
Theme <- create_theme(
  adminlte_color(
    red = "#FF4719"
  ),
  adminlte_sidebar(
    dark_bg = "#293745",
    dark_hover_bg = "#3CAAFF",
  )
)

## Assign File Paths
Path0 <- "C:/Users/Username/Fiji.app/ImageJ-win64.exe --ij2 --run C:/Users/Username/Fiji.app/macros/TestingShiny.ijm"

ui <- dashboardPage(skin = "red",
                    
                    dashboardHeader(
                      title = h4(HTML("Test"))),
                    
                    dashboardSidebar(
                      sidebarMenu(id = "sidebarid",       
                                  menuItem("Test Run", tabName = "info"))),
                                    
                    
                    dashboardBody(
                      use_theme(Theme),
                      tabItems(
                        tabItem(tabName = "info",  
                                fluidRow(
                                  column( width = 4,
                                          fluidRow(
                                  actionBttn(inputId = "go", label = "Go!"),
                                  tableOutput(outputId = "text"))
                        )
  )))))  


server <- function(input, output, session) {
  ## Sets observeEvent with eventReactive for Go button click  
  observeEvent(input$go, {
    
    ## Runs Fiji and accompanying macro
    system(Path0) 
    
    ## Pulls Result file from Output folder
    Result <- eventReactive(input$go, {read.delim(Path1)})
    Filepath1 <- here("Output", "Log.txt")
    write.csv(Result(), Filepath1 , row.names = FALSE)
    ## Displays the result
    output$text <- renderTable(align = 'c', {Result()})
    
  })}


shinyApp(ui, server)

请问是否可以传递客户端本地的Fiji应用及宏文件路径,使Fiji在客户端运行并将结果回传至Shiny App?shinyFiles或shiny::fileInput()是否可行?


解决方案

核心结论

可以实现让客户端运行本地Fiji并回传结果,但要注意:部署在shinyapps.io的Shiny App,服务器端代码运行在云端,无法直接调用客户端本地程序或访问本地文件路径,必须调整为「客户端主动触发操作+结果上传」的模式。以下是两种可行方案:


方案1:用fileInput()实现结果回传(简单易实现,适合web部署)

此方案通过引导用户手动完成Fiji操作,再上传结果,无需复杂配置:

  1. 让用户上传待分析图像(如果宏需要处理特定图像):
    fileInput("image_upload", "上传待分析图像", accept = c("image/tiff", "image/png", "image/jpeg"))
    
  2. 提供宏文件下载:将你的TestingShiny.ijm放在App的www目录,让用户下载到本地:
    downloadButton("download_macro", "下载分析宏文件")
    
    服务器端对应逻辑:
    output$download_macro <- downloadHandler(
      filename = function() { "TestingShiny.ijm" },
      content = function(file) {
        file.copy("www/TestingShiny.ijm", file)
      }
    )
    
  3. 引导用户运行Fiji:在UI中添加提示文本,告知用户打开本地Fiji,加载下载的宏和上传的图像,执行分析后导出结果文件(如.txt或.csv)。
  4. 让用户上传结果文件:
    fileInput("result_upload", "上传分析结果", accept = c(".txt", ".csv"))
    
  5. 服务器端读取并展示结果:
    observeEvent(input$result_upload, {
      result_df <- read.delim(input$result_upload$datapath)
      output$text <- renderTable(result_df, align = 'c')
    })
    

方案2:用shinyFiles获取本地路径(进阶,适合桌面打包)

shinyFiles可以让用户选择本地Fiji和宏文件的路径,但服务器端无法直接调用客户端程序,需借助额外工具触发:

  1. 安装并加载shinyFiles:
    pacman::p_load(shinyFiles)
    
  2. UI中添加路径选择组件:
    shinyFilesButton("fiji_exe", "选择Fiji可执行文件", "选择ImageJ-win64.exe", multiple = FALSE)
    shinyFilesButton("macro_file", "选择宏文件", "选择TestingShiny.ijm", multiple = FALSE)
    
  3. 服务器端获取路径并生成命令:
    observe({
      volumes <- getVolumes()
      shinyFileChoose(input, "fiji_exe", roots = volumes, session = session)
      shinyFileChoose(input, "macro_file", roots = volumes, session = session)
      
      if (!is.null(input$fiji_exe) && !is.null(input$macro_file)) {
        fiji_path <- parseFilePaths(volumes, input$fiji_exe)$datapath
        macro_path <- parseFilePaths(volumes, input$macro_file)$datapath
        # 生成可在本地执行的命令
        run_cmd <- paste0('"', fiji_path, '" --ij2 --run "', macro_path, '"')
        # 将命令传递给客户端提示用户执行
        session$sendCustomMessage(type = "showCmd", message = run_cmd)
      }
    })
    
  4. 客户端提示用户复制命令执行:在UI中添加JavaScript,接收服务器传递的命令并展示:
    tags$script('
      Shiny.addCustomMessageHandler("showCmd", function(cmd) {
        alert("请复制以下命令在本地CMD中执行:\\n" + cmd);
      });
    ')
    

    注意:普通浏览器出于安全限制,无法直接通过JavaScript调用本地程序。如果要完全自动化触发,建议将Shiny App用shinyElectron打包成桌面应用,可直接调用本地命令。


关键注意事项

  • 部署在shinyapps.io的App,所有system()或processx::run()调用都是在云端服务器执行,完全无法访问用户本地资源,必须放弃「服务器主动调用客户端程序」的思路。
  • 如果追求全自动化体验,不适合部署在web端,更适合打包成桌面Shiny App。

内容的提问来源于stack exchange,提问作者MBS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 15:23:15