【问题标题】:Open external file with Electron用 Electron 打开外部文件
【发布时间】:2015-08-03 13:50:03
【问题描述】:

我有一个正在运行的 Electron 应用程序,到目前为止运行良好。对于上下文,我需要运行/打开一个外部文件,该文件是一个 Go-lang 二进制文件,它将执行一些后台任务。 基本上,它将充当后端并公开 Electron 应用程序将使用的 API。

到目前为止,这就是我所了解的:

  • 我尝试使用 child_process 以“节点方式”打开文件,但可能由于路径问题,我无法打开示例 txt 文件。

  • Electron API 公开了一个 open-file 事件,但它缺少文档/示例,我不知道它是否有用。

就是这样。 如何在 Electron 中打开外部文件?

【问题讨论】:

    标签: electron


    【解决方案1】:

    我知道这并不完全符合您的规范,但它确实将您的 golang 二进制文件和 Electron 应用程序完全分开。

    我这样做的方式是将 golang 二进制文件公开为 Web 服务。像这样

    package main
    
    import (
        "fmt"
        "net/http"
    )
    
    func handler(w http.ResponseWriter, r *http.Request) {
        //TODO: put your call here instead of the Fprintf
        fmt.Fprintf(w, "HI there from Go Web Svc. %s", r.URL.Path[1:])
    }
    
    func main() {
        http.HandleFunc("/api/someMethod", handler)
        http.ListenAndServe(":8080", nil)
    }
    

    然后从 Electron 只需使用 javascript 函数对 Web 服务进行 ajax 调用。像这样(你可以使用 jQuery,但我发现这个纯 js 工作正常)

    function get(url, responseType) {
        return new Promise(function(resolve, reject) {
          var request = new XMLHttpRequest();
          request.open('GET', url);
          request.responseType = responseType;
    
        request.onload = function() {
        if (request.status == 200) {
          resolve(request.response);
        } else {
          reject(Error(request.statusText));
        }
      };
    
      request.onerror = function() {
        reject(Error("Network Error"));
      };
    
      request.send();
    });
    

    使用该方法,您可以执行类似的操作

    get('localhost/api/somemethod', 'text')
      .then(function(x){
        console.log(x);
      }
    

    【讨论】:

    • 这是一种有趣的方法。但是当我们启动 Electron 时,我们如何启动这个二进制文件呢?使用child_process 添加示例。这是一个有趣的想法。
    • 问题说明“它将充当后端并公开 Electron 应用程序将使用的 API”。我的解决方案是拥有一个正在运行的 Web 服务。它不会由 Electron 应用程序启动。它甚至可能不在同一台机器上。我认为原始问题中没有任何内容暗示 Electron 应用程序必须启动后端。
    • OP 声明他需要“运行/打开一个外部文件,它是一个 Golang 二进制文件”。
    • 尽管有反对意见,但这是一种合法的方法,例如,它在 vscode 中很常见,将插件的一部分作为服务启动,然后有一个电子端插件,该插件通过 http 与另一部分通信。
    【解决方案2】:

    Electron 允许使用 nodejs 包

    换句话说,像在 node 中一样导入 node 包,例如:

    var fs = require('fs');
    

    要运行 golang 二进制文件,您可以使用 child_process 模块。文档很详尽。

    编辑:你必须解决路径差异。 open-file 事件是客户端事件,由窗口触发。这里不是你想要的。

    【讨论】:

      【解决方案3】:

      您可能想研究几个 api,看看哪些对您有帮助。

      fs

      fs 模块允许您直接打开文件进行读写。

      var fs = require('fs');
      fs.readFile(p, 'utf8', function (err, data) {
        if (err) return console.log(err);
        // data is the contents of the text file we just read
      });
      

      路径

      path 模块允许您以与平台无关的方式构建和解析路径。

      var path = require('path');
      var p = path.join(__dirname, '..', 'game.config');
      

      外壳

      shell api 是一个纯电子 api,您可以使用它在给定路径上执行文件,这将使用操作系统默认应用程序打开文件。

      const {shell} = require('electron');
      // Open a local file in the default app
      shell.openItem('c:\\example.txt');
      
      // Open a URL in the default way
      shell.openExternal('https://github.com');
      

      子进程

      假设您的 golang 二进制文件是可执行文件,那么您将使用 child_process.spawn 调用它并与之通信。这是一个节点 API。

      var path = require('path');
      var spawn = require('child_process').spawn;
      
      var child = spawn(path.join(__dirname, '..', 'mygoap.exe'), ['game.config', '--debug']);
      // attach events, etc.
      

      插件

      如果您的 golang 二进制文件不是可执行文件,那么您需要制作一个 native addon 包装器。

      【讨论】:

      • 看来shell.openItem已经改成了shell.openPath
      【解决方案4】:

      也许你正在寻找这个?

      dialog.showOpenDialog参考:https://www.electronjs.org/docs/api/dialog

      如果使用 electron@13.1.0,你可以这样做:

      const { dialog } = require('electron')
      console.log(dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] }))
      
      dialog.showOpenDialog(function(file_paths){
        console.info(file_paths)  // => this gives the absolute path of selected files.
      })
      
      

      当上面的代码被触发时,你可以看到一个像这样的“打开文件对话框”(win/mac/linux的不同视图样式)

      【讨论】:

        【解决方案5】:

        我也完全在这个问题上苦苦挣扎,几乎七年后,文档并不清楚 Linux 的情况。

        因此,在 Linux 上它在这方面属于 Windows 处理,这意味着您必须查看主处理器中的 process.argv 全局,数组中的第一个值是触发应用程序的路径。第二个参数(如果存在)保存请求打开应用程序的路径。例如,这是我的测试用例的输出:

        Array(2)
        0: "/opt/Blueprint/b-test"
        1: "/home/husayngonzalez/2022-01-20.md"
        length: 2
        

        因此,当您创建一个新窗口时,您检查process.argv 的长度,如果它大于1,即= 2,则意味着您有一个请求使用您的应用程序打开的路径。

        假设您将应用程序打包为能够处理这些文件,并且您将操作系统设置为请求您的应用程序打开这些文件。

        【讨论】:

          猜你喜欢
          • 2022-12-16
          • 2016-08-11
          • 1970-01-01
          • 1970-01-01
          • 2015-02-28
          • 2017-02-17
          • 2010-10-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多