nodejs 不用 electron 实现打开文件资源管理器并选择文件

前言

最近在开发一些小脚本,用 nodejs 实现。其中很多功能需要选择一个/多个文件,或者是选择一个文件夹。

最初的实现是手动输入一个目录(这个只是一个普通的终端文本输入,所以按下 tab 没有路径提示),非常的麻烦,而且很容易输错。

这种情况下网上给出的解决方案都是 electron。但是我一个小脚本用 electron 属实有点夸张了,后来转念一想可以通过 powershell 来实现类似的功能。

通过命令唤醒文件选择器

通过 cmd / prowershell 唤醒文件选择器

对 powershell 不熟悉的我唰的一声打开了 gpt,gpt 不负众望 很快给出了答案

注意这里有区别:cmd 终端中需要调用 powershell.exe
如果当前已经是在 powershell 终端的话,直接运行对应的指令即可

  • 在 cmd 中运行:
powershell.exe -Command "& {Add-Type -AssemblyName System.Windows.Forms; $FileDialog = New-Object System.Windows.Forms.OpenFileDialog; $result = $FileDialog.ShowDialog(); if ($result -eq 'OK') { Write-Output $FileDialog.FileName }}"
  • 在 powershell 中运行:
& {Add-Type -AssemblyName System.Windows.Forms; $FileDialog = New-Object System.Windows.Forms.OpenFileDialog; $result = $FileDialog.ShowDialog(); if ($result -eq 'OK') { Write-Output $FileDialog.FileName }}

运行效果:选择文件后终端会输出你选择的文件的全路径

pFSiuTJ.png

在 nodejs 调用 cmd 命令

const { exec, execSync } = require('child_process')

const command = `powershell.exe -Command "& {Add-Type -AssemblyName System.Windows.Forms; $FileDialog = New-Object System.Windows.Forms.OpenFileDialog; $result = $FileDialog.ShowDialog(); if ($result -eq 'OK') { Write-Output $FileDialog.FileName }}"`

// 异步执行
exec(command, (error, file) => {
  console.log(error, file)
})

// 同步执行
const filePath = execSync(command)
console.log('选择的文件', filePath)

到这结束了吗?并没有,我选择的是一个包含中文名称的路径,输入结果如下:

pFSiI10.png

几个小问题:

  1. execSync 同步执行的代码返回的是 Buffer 类型
    • 可以用 filePath.toString()获取实际的路径
  2. 选择的文件/文件夹包含中文,返回乱码的问题
    • 这个需要设置终端的编码类型,也就是在执行上面的命令执行先执行 chcp 650
  3. 遇到执行警告:libpng warning: iCCP: cHRM chunk does not match sRGB
    • 卸载 QQ 拼音 😃 (虽然我也不知道具体是哪里的问题,不过确实是 QQ 拼音引起的)

调整后执行效果如下:

pFSFY3q.png

如何实现多选文件 / 选择文件夹?

  • 选择目录
# 加载 Windows.Forms 程序集
Add-Type -AssemblyName System.Windows.Forms

# 创建 FolderBrowserDialog 对象
$folderDialog = New-Object System.Windows.Forms.FolderBrowserDialog

# 设置对话框的属性
$folderDialog.Description = "请选择文件夹"
$folderDialog.RootFolder = [System.Environment+SpecialFolder]::MyComputer

# 显示文件夹选择对话框
$result = $folderDialog.ShowDialog()

# 检查用户是否点击了 "确定" 按钮
if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
    # 输出所选文件夹的路径
    Write-Output $folderDialog.SelectedPath
} else {
    # 用户取消选择,这里输出空路径
    Write-Output ""
}

合并成一行代码则是:

  • cmd 执行:
powershell.exe -Command "& {Add-Type -AssemblyName System.Windows.Forms; $folderDialog = New-Object System.Windows.Forms.FolderBrowserDialog; $folderDialog.Description = '请选择文件夹'; $folderDialog.RootFolder = [System.Environment+SpecialFolder]::MyComputer; $result = $folderDialog.ShowDialog(); if ($result -eq [System.Windows.Forms.DialogResult]::OK) { Write-Output $folderDialog.SelectedPath } else { Write-Output '' }}"

多选文件同理:

# 加载 Windows.Forms 程序集
Add-Type -AssemblyName System.Windows.Forms

# 创建 OpenFileDialog 对象
$fileDialog = New-Object System.Windows.Forms.OpenFileDialog

# 设置对话框的属性
$fileDialog.Multiselect = $true
$fileDialog.Title = "请选择文件"
$fileDialog.Filter = "All Files (*.*)|*.*"

# 显示文件选择对话框
$result = $fileDialog.ShowDialog()

# 检查用户是否点击了 "确定" 按钮
if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
    # 输出所选文件的路径(数组)
    Write-Output $fileDialog.FileNames
} else {
    # 用户取消选择
    Write-Output ""
}

合并为一行命令:

powershell.exe -Command "& {Add-Type -AssemblyName System.Windows.Forms; $fileDialog = New-Object System.Windows.Forms.OpenFileDialog; $fileDialog.Multiselect = $true; $fileDialog.Title = '请选择文件'; $fileDialog.Filter = 'All Files (*.*)|*.*'; $result = $fileDialog.ShowDialog(); if ($result -eq [System.Windows.Forms.DialogResult]::OK) { Write-Output $fileDialog.FileNames } else { Write-Output '' }}"

一些细节

  • 如果是选择单个文件/选择文件目录。输出的结果会包含一些前后空格和换行,所以需要通过 filePath.trim() 处理一下多余的字符
  • 如果是多选的文件,返回的是字符串,每个文件以换行隔开的,也是需要自行处理
  • 眼尖的朋友可能发现了在多选的命令中有一段代码:$fileDialog.Filter = "All Files (*.*)|*.*" 可以用于设置可选择的文件类型的。
    对应的是这个功能:
    pFSkBsf.png
    就不再细说了~ 自行摸索

MacOS 如何实现用命令打开选择器

以下的命令完全来自 GPT,并没有经过测试。自行判断代码是否正常运行 (原谅我并没有 mac)

  • 选择一个文件
osascript -e 'POSIX path of (choose file with prompt "请选择一个文件")'
  • 选择一个目录
osascript -e 'POSIX path of (choose folder with prompt "请选择一个目录")'
  • 选择多个文件
    (略)gpt 给出的答案非常的长,而且我没电脑试验,所以就不放代码了,有试验过的可以告诉我补充一下~

最后

至此,我的小脚本使用体验已经拉满,再也不用一个个输入文件路径了。

总结下所有用到的命令:

  • Windows

    • 选择单个文件
      powershell.exe -Command "& {Add-Type -AssemblyName System.Windows.Forms; $FileDialog = New-Object System.Windows.Forms.OpenFileDialog; $result = $FileDialog.ShowDialog(); if ($result -eq 'OK') { Write-Output $FileDialog.FileName }}"
    
    • 选择文件目录
    powershell.exe -Command "& {Add-Type -AssemblyName System.Windows.Forms; $folderDialog = New-Object System.Windows.Forms.FolderBrowserDialog; $folderDialog.Description = '请选择文件夹'; $folderDialog.RootFolder = [System.Environment+SpecialFolder]::MyComputer; $result = $folderDialog.ShowDialog(); if ($result -eq [System.Windows.Forms.DialogResult]::OK) { Write-Output $folderDialog.SelectedPath } else { Write-Output '' }}"
    
    • 选择多个文件
    powershell.exe -Command "& {Add-Type -AssemblyName System.Windows.Forms; $fileDialog = New-Object System.Windows.Forms.OpenFileDialog; $fileDialog.Multiselect = $true; $fileDialog.Title = '请选择文件'; $fileDialog.Filter = 'All Files (*.*)|*.*'; $result = $fileDialog.ShowDialog(); if ($result -eq [System.Windows.Forms.DialogResult]::OK) { Write-Output $fileDialog.FileNames } else { Write-Output '' }}"
    
  • MacOS

    • 选择一个文件
    osascript -e 'POSIX path of (choose file with prompt "请选择一个文件")'
    
    • 选择一个目录
    osascript -e 'POSIX path of (choose folder with prompt "请选择一个目录")'
    
    • 选择多个文件

完 ~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/300007.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

说反话-加强版

主要&#xff1a;使用strtok函数&#xff08;将字符串以空格分开&#xff09;&#xff08;若不了解strtok函数&#xff0c;我在其它文章已说明&#xff09; #include <stdio.h> #include <string.h> int main() { int i 0; int z 0; char* str[5000…

测试组合生成器-allpairspy

1、前言 在我们写功能用例时&#xff0c;常常会遇到多个参数有很多的选项&#xff0c;而如果想把这些参数值都要覆盖执行的话&#xff0c;工作量可想而知。那有没有什么办法既可以减少用例数量&#xff0c;也可以保证用例质量又降低测试时间成本&#xff0c;本篇将介绍一款工具…

强化学习的数学原理学习笔记 - 时序差分学习(Temporal Difference)

文章目录 概览&#xff1a;RL方法分类时序差分学习&#xff08;Temporal Difference&#xff0c;TD&#xff09;TD for state valuesBasic TD&#x1f7e1;TD vs. MC &#x1f7e6;Sarsa (TD for action values)Basic Sarsa变体1&#xff1a;Expected Sarsa变体2&#xff1a;n-…

Halcon区域的最大、最小灰度值min_max _gray

Halcon区域的最大、最小灰度值 除了可以使用gray_features算子提取区域中的最大与最小灰度值外&#xff0c;还可以使用min_max gray 算子计算区域的最大与最小灰度值&#xff0c;区别是后者更具灵活性。min_maxgray 算子的原理是基于灰度直方图&#xff0c;取波峰和谷底之间的…

学习笔记——C++运算符之比较运算符

作用&#xff1a;用于表达式的比较&#xff0c;并返回一个真值或假值 比较运算符有以下符号&#xff1a; #include<bits/stdc.h> using namespace std; int main(){//int a10;int b20;cout<<(ab)<<endl;//0//!cout<<(a!b)<<endl;//1//>cout&…

行走在深度学习的幻觉中:问题缘由与解决方案

如何解决大模型的「幻觉」问题&#xff1f; 我们在使用深度学习大模型如LLM&#xff08;Large Language Models&#xff09;时&#xff0c;可能会遇到一种被称为“幻觉”的现象。没错&#xff0c;它并不是人脑中的错觉&#xff0c;而是模型对特定模式的过度依赖&#xff0c;这…

【Docker-Dev】Mac M2 搭建docker的redis环境

Redis的dev环境docker搭建 1、前言2、官方文档重点信息提取2.1、创建redis实例2.2、使用自己的redis.conf文件。 3、单机版redis搭建4、redis集群版4.1、一些验证4.2、一些问题 结语 1、前言 本文主要针对M2下&#xff0c;相应进行开发环境搭建&#xff0c;然后做一个文档记录…

美食管理与推荐系统Python+Django网站系统+协同过滤推荐算法【计算机课设】

一、介绍 美食管理与推荐系统。本系统使用Python作为主要开发语言开发的一个美食管理推荐网站平台。 网站前端界面采用HTML、CSS、BootStrap等技术搭建界面。后端采用Django框架处理用户的逻辑请求&#xff0c;并将用户的相关行为数据保存在数据库中。通过Ajax技术实现前后端的…

Linux之Shell编程

shell是什么 shell是一个命令行解释器&#xff0c;他为用户提供一个向linux内核发送请求以便运行程序的界面系统级程序&#xff0c;用户可以用shell来启动&#xff0c;挂起&#xff0c;停止甚至编写一些程序。 shell脚本的执行方式 脚本格式要求 脚本以#!/bin/bash开头脚本需…

JavaScript基础(24)_dom查询练习(一)

<!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><link rel"stylesheet" href"../browser_default_style/reset.css"><title>dom查询练习一</title><style>.text {widt…

JS手写apply,call,bind函数

本篇文章咱们来手写简易版的apply&#xff0c;call&#xff0c;bind函数。 实现思路 首先咱们需要思考下这三个函数放到哪里比较合适&#xff0c;因为这三个函数是被函数对象调用的&#xff0c;并且每个函数都可以调用&#xff0c;所以不难想到有一个位置非常合适&#xff0c;…

解决Docker报错问题:Docker Desktop – Unexpected WSL error

最近因为准备在NAS上通过Docker容器方式安装MYSQL&#xff0c;发现https://hub.docker.com网站被墙了&#xff0c;无法自动安装&#xff0c;同时又找不到靠谱的离线镜像&#xff0c;所以准备在Window上安装Docker&#xff0c;通过电脑的网络代理制作离线镜像再上传到NAS上。 在…

媒体捕捉-iOS自定义二维码扫描功能

引言 随着iOS 7引入AV Foundation框架&#xff0c;二维码扫描功能已经成为iOS应用程序中不可或缺的一部分。现今&#xff0c;几乎每个应用都充分利用这一功能&#xff0c;为用户提供了诸如扫码登录、扫码填充等丰富多彩的便捷体验。这项技术不仅丰富了应用功能&#xff0c;也为…

校园-智慧门禁(卡码脸)解决方案

前言 入职新公司也已经一年有余&#xff0c;入职后主要从事的是门禁项目&#xff0c;公司设计的项目是偏saas化的智慧门禁系统&#xff0c;目前已经在多所大学上线&#xff0c;以下是对该项目的个人总结复盘。 一、系统主要功能和扩展功能 可实现学校统一门禁设备管理可实现人…

第14届蓝桥杯省赛scratch真题+解题思路+详细解析

一、选择题 一共有5道选择题&#xff0c;每题10分&#xff0c;共50分&#xff0c;严禁使用程序验证&#xff0c;选择题不答和答错不得分。 1. 运行以下程序&#xff0c;舞台上能看到几只小猫&#xff1f;&#xff08; &#xff09; A. 4 B. 5 C. 6 D. 7 答案&#xff…

软件测试|Linux三剑客之grep命令详解

简介 grep是一款在 Linux 和类 Unix 系统中广泛使用的文本搜索工具。它的名字来源于 Global Regular Expression Print&#xff08;全局正则表达式打印&#xff09;&#xff0c;它的主要功能是根据指定的模式&#xff08;正则表达式&#xff09;在文本文件中搜索并打印匹配的行…

reiserfs文件系统的磁盘布局

reiserfs文件系统的磁盘布局比较简单&#xff0c;它把整块分区分成相同大小的block块&#xff0c;一个block块的大小默认是4K&#xff0c;而最大块数未2^32次方&#xff0c;即一个分区最大大小为16TB。 reiserfs文件系统分区的前64KB总是为分区标签&#xff08;partition labe…

推荐收藏!万字长文带入快速使用 keras

这些年&#xff0c;有很多感悟&#xff1a;一个人精力是有限的&#xff0c;一个人视野也有有限的&#xff0c;你总会不经意间发现优秀人的就在身边。 看我文章的小伙伴应该经常听我说过的一句话&#xff1a;技术要学会交流、分享&#xff0c;不建议闭门造车。一个人可以走的很…

CSS基础笔记-03选择器

CSS基础笔记系列 《CSS基础笔记-01CSS概述》《CSS基础笔记-02动画》 前言 在前面两篇博客中&#xff0c;我实际上已经使用过了选择器。但到底什么是选择器、有什么作用&#xff0c;我反而不能表达出来。因此&#xff0c;决定记录了我的学习和思考。 什么是选择器 selector…

基于 HTTPS 协议配置 Git 连接 GitHub

文章目录 0.安装 Git1.注册 GitHub 账号2.配置 Git 的用户名和邮箱3.远程连接 GitHub 有两种传输协议4.基于 SSH 协议配置 Git 连接 GitHub5.基于 HTTPS 协议配置 Git 连接 GitHub5.1 创建 GitHub 个人访问令牌5.2 有两种方法将本地仓库和远程仓库关联起来5.2.1 第一种方法&…