【问题标题】:Electron: get full path of uploaded fileElectron:获取上传文件的完整路径
【发布时间】:2016-11-26 14:01:42
【问题描述】:

我现在正在使用 Electron 构建 GUI。 (如桌面应用的 PhoneGap)

有没有办法为<input type="file"> 中签入的文件启用完整路径?
现在安装C:\fakepath\dataset.zip。 (目录名不是“fakepath”,而是document.getElementById("myFile").value的值)

或者,还有其他选择文件的方法吗?

【问题讨论】:

  • C:\fakepath\dataset.zip 是完整路径。什么意思?
  • 不,目录名不是fakepath,但这正是我从document.getElementById("myFile").value 得到的。
  • 你无法获取这样的输入文件。
  • @HenriqueBarcelos -- 不在最终用户浏览器中,但您可以在具有提升权限的运行时环境中执行此操作,例如 Electron。此外,c:\fakepath\<filename> 不是完整路径,它是众所周知的 faked path,由于遗留原因而存在。

标签: node.js electron


【解决方案1】:

接受的答案非常适合原始问题,但来自@Piero-Divasto 的答案更适合我的目的。

我需要的是一个可能相当大的目录的路径名。使用接受的答案,这可以在处理目录内容时阻塞主进程几秒钟。使用dialog.showOpenDialog(...) 可以让我得到近乎即时的响应。唯一不同的是dialog.showOpenDialog 不再接受回调函数,而是返回一个promise:

ipcMain.on("open-file-dialog-for-dir", async event => {
  const dir = await dialog.showOpenDialog({ properties: ["openDirectory"] });
  if (dir) {
    event.sender.send("selected-dir", dir.filePaths[0]);
  }
});

【讨论】:

    【解决方案2】:
    <script>
    
        const electron = require('electron');
        const { ipcRenderer } = electron;
        const ko = require('knockout')
        const fs = require('fs');
        const request = require('request-promise');
    
        // replace with your own paths
        var zipFilePath = 'C:/Users/malco/AppData/Roaming/Wimpsdata/Wimpsdata.zip';
        var uploadUri = 'http://localhost:59887/api/Collector/Upload'
    
        var request = require('request');
        request.post({
            headers: { 'content-type': 'application/zip' },
            url: uploadUri,
            body: fs.createReadStream(zipFilePath)
        }, function (error, response, body) {
            console.log(body);
            location.href = 'ScanResults.html';
        });
    </script>
    

    ASP .NET WebAPI 控制器

    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.IO;
    using System.IO.Compression;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Threading.Tasks;
    using System.Web;
    using System.Web.Http;
    using Wimps.Services.Business;
    
    namespace Wimps.Services.Controllers
    {
        public class CollectorController : ApiController
        {
    
            public async Task<bool> Upload()
            {
                try
                {
                    var fileuploadPath = ConfigurationManager.AppSettings["FileUploadLocation"];
    
                    var provider = new MultipartFormDataStreamProvider(fileuploadPath);
                    var content = new StreamContent(HttpContext.Current.Request.GetBufferlessInputStream(true));
                    foreach (var header in Request.Content.Headers)
                    {
                        content.Headers.TryAddWithoutValidation(header.Key, header.Value);
                    }
    
                    Byte[] byteArray = await content.ReadAsByteArrayAsync();
    
                    string newFileName = Guid.NewGuid().ToString();
                    string newFilePath = fileuploadPath + "\\" + newFileName + ".zip";
                    if (File.Exists(newFilePath))
                    {
                        File.Delete(newFilePath);
                    }
    
                    File.WriteAllBytes(newFilePath, byteArray);
    
                    string unzipTo = fileuploadPath + "\\" + newFileName;
                    Directory.CreateDirectory(unzipTo);
    
                    DirectoryInfo di = new DirectoryInfo(unzipTo);
                    foreach (FileInfo file in di.GetFiles())
                    {
                        file.Delete();
                    }
    
                    ZipFile.ExtractToDirectory(newFilePath, unzipTo);
    
    
    
                    return true;
                }
                catch (Exception e)
                {
                    // handle exception here
                    return false;
                }
            }
        }
    }
    

    需要在 web config 中添加密钥以进行文件上传

    <configuration>
      <appSettings>
    ... other keys here
        <add key="FileUploadLocation" value="C:\Temp\Uploads" />
      </appSettings>
    

    应用程序配置的其余部分 ... ...

    【讨论】:

      【解决方案3】:

      Electron 将path 属性添加到File 对象,因此您可以使用以下方法从输入元素获取真实路径:

      document.getElementById("myFile").files[0].path
      

      【讨论】:

        【解决方案4】:
        <script>const electron = require('electron');</script>
        <button id="myFile" onclick="this.value=electron.remote.dialog.showOpenDialog()[0]">UpdateFile</button>
        

        现在,document.getElementById("myFile").value 将包含所选文件的完整路径。

        【讨论】:

          【解决方案5】:

          根据这个答案How to get full path of selected file on change of <input type=‘file’> using javascript, jquery-ajax?,出于安全原因,无法执行您正在尝试的操作。

          但是,您可以像我在我从事的电子项目中所做的那样做一些工作。

          1. 创建一个 HTML 按钮
          2. 然后在渲染进程中为你之前创建的按钮创建一个事件监听器。

            const ipc = require('electron').ipcRenderer;
            const buttonCreated = document.getElementById('button-created-id');
            
            buttonCreated.addEventListener('click', function (event) {
                ipc.send('open-file-dialog-for-file')
            });
            
          3. 然后在主进程中使用showOpenDialog 选择一个文件,然后将full path 发送回渲染器进程。

            ipc.on('open-file-dialog-for-file', function (event) {
             if(os.platform() === 'linux' || os.platform() === 'win32'){
                dialog.showOpenDialog({
                    properties: ['openFile']
                }, function (files) {
                   if (files) event.sender.send('selected-file', files[0]);
                });
            } else {
                dialog.showOpenDialog({
                    properties: ['openFile', 'openDirectory']
                }, function (files) {
                    if (files) event.sender.send('selected-file', files[0]);
                });
            }});
            
          4. 然后在渲染进程中你会得到full path

            ipc.on('selected-file', function (event, path) {
                console.log('Full path: ', path);
            });
            

          因此您可以有与输入类型文件类似的行为并获取完整路径。

          【讨论】:

          • “出于安全原因,无法执行您正在尝试的操作” -- 这适用于最终用户浏览器,但不适用于 Electron。我相信你可以简单地使用input.files[0].path,在currently accepted answer中也有描述。
          猜你喜欢
          • 2013-11-24
          • 1970-01-01
          • 2011-04-17
          • 2016-03-13
          • 2012-07-13
          • 1970-01-01
          • 2020-12-14
          • 2013-06-29
          • 1970-01-01
          相关资源
          最近更新 更多