Directory Opus与外部工具集成

前言

Directory Opus 与外部工具集成,大方向无非就两种:由外部工具调用 Directory Opus通过 Directory Opus 调用外部的工具

外部工具调用 Directory Opus

Directory Opus 提供了一个二进制程序 dopusrt,位于软件的根目录。可以通这个程序,在外部调用命令和操作 DOpus。

比如在 CMD 或 PowerShell 中运行以下命令,将使用 DOpus 的查找功能在 C:\Users 中查找文件名中包含 catdog 的文件。

& 'C:\Program Files\GPSoftware\Directory Opus\dopusrt.exe' /acmd Find NAME="cat dog" IN C:\Users ANYWORD 

效果相当于直接在 DOpus 中执行内部命令:

Find NAME="cat dog" IN C:\Users ANYWORD 

但是说实话,我目前并没有遇到什么实际场景需要从外部调用 DOpus 的。

像上面的文件搜索,我一般直接用 Listary 这种启动器就能完成了,并且本身就与 DOpus 有一定程度的集成。完全没必要走外部命令调用的形式...况且 DOpus 本身的查找功能相当的慢,远不如索引好的启动器或 Everything 搜索的快。除非你是想要查找 DOpus标签之类只能用 DOpus 查找面板搜索的数据,不然还不如直接用启动器查找。

总而言之,这个方向对我来说有点别扭,甚至是负效率。不想为了集成而硬使用功能,因此没有进行过多的探究。

不过有过一种想法,就是和 通过 Directory Opus 调用外部工具 结合起来,将脚本的功能实现完全外置,在外置脚本中调用 内部命令 等功能。

通过 Directory Opus 调用外部工具

在 DOpus 中调用外部工具或脚本,是我最常用的集成方式。

DOpus 本身是支持自定义脚本的,但是由于设计和历史原因,Opus 使用 JSCriptVBScript 作为脚本语言。JScript 不同于现在 Web浏览器Node.js 中使用的 JavaScript,语法和特性都是相当的古老(差不多相当于 ES3 吧...),并且没有现代工具链的支持,写脚本的体验是相当的难受(特别是对于喜欢用现代 JS 特性的人来说)。
虽然现在有 AI 加持,但是实际上 AI 生成的结果往往也不是很理想。并且官方也没有打算引入新的脚本语言。

因此对于一些稍微复杂的脚本需求,我往往会选择通过调用外置脚本/工具的方式来实现。
对于喜欢用 DOpus 此类效率工具的人来说,电脑上基本上也有会 PythonNode.js 环境,因此我喜欢用 Python 或 JavaScript 来作为外部的脚本语言。

当然,比较简单或对 DOpus 依赖性比较强的脚本(调用 DOpus 命令等),我还是会用 DOpus 本身的脚本模块来完成。

说了这么多,这个方向的集成,实际上就是利用 DOpus 的界面,将当前选中文件、路径、对话框输入内容等作为参数,传递给脚本。

为了更好的集成,以及配置导入导出迁移的通用性,对于常用电脑,我个人一般会保持以下习惯:

  1. 尽量使用包管理器来安装工具。
    我喜欢用 scoop,可能对于一些人来说输入命令有点麻烦,不过好处也显而易见。可以通过命令的形式进行自动化、半自动化操作。可以方便的进行导入和导出。并且安装应用会自动管理环境变量。
  2. 利用好 DOpus 的别名以及规划目录
    DOpus 文件夹别名Folder Aliases 的文件夹别名模块,对统一管理路径和集成非常的有用,这可以保证,当我们因为迁移、还原备份等原因需要修改脚本路径时,不需要修改脚本中硬编码的路径,而是编辑别名对应的目录即可。别名本身的大小写不敏感的,即 MyNamemyname 是一样的。

对于外部脚本,如果你会使用 Git 之类的版本管理工具,最佳实践可能是在 DOpus 中设置脚本目录的别名,比如 script_pyscript_js,然后在 DOpus 中就可以通过别名来使用,比如执行内置命令 GO /script_pyGO {alias|script_py} 都可以跳转到相应目录。

对于一些比较轻量的脚本,也可以放在 DOpus 本身的脚本管理目录 Script AddIns 中,可以通过内置别名 GO /Scripts 访问。把脚本放这个目录下的好处是:与其他脚本文件统一管理,可以利用 DOpus 的备份恢复来同步脚本。并且在 DOpus 内部可以使用内置的别名。

案例 1:通过按钮调用外部脚本

这是一个挺常用的场景。

比如选中某些文件,然后点击一个自定义按钮,将选中的文件作为目标参数传给脚本。

比如我在 Script AddIns/Extra 目录中有一个自定义的外部脚本 trans_text.py,接受两个参数: -i 表示目标文件的绝对路径(多个),-t 表示目标语言。下方的脚本仅作为示例,功能就是在控制台输出接收到的参数,并且在同目录下生成一个日志文件。

# trans_text.py
import argparse
import logging
from pathlib import Path

def main():
    # 日志文件放在脚本同目录
    script_dir = Path(__file__).parent
    log_file = script_dir / "trans_text.log"
    # 配置日志
    logging.basicConfig(
        filename=log_file,
        level=logging.INFO,
        format="%(asctime)s - %(message)s",
        encoding='utf-8'
    )
    parser = argparse.ArgumentParser(description="输出传入的文件路径与目标语言")
    parser.add_argument("-i", "--inputs", nargs="+", required=True, help="文件路径列表")
    parser.add_argument("-t", "--target", required=True, help="目标语言")
    args = parser.parse_args()
    # 输出内容
    msg = f"目标语言:{args.target}\n接收到 {len(args.inputs)} 个文件路径:\n" + "\n".join(args.inputs)
    # 打印到控制台
    print(msg)
    # 写入日志
    logging.info(msg)

if __name__ == "__main__":
    main()

在命令行中调用方式是:

python "脚本目录的绝对路径\trans_text.py" -i "文件A路径" "文件B路径" -t "zh_CN"

我希望实现:在 DOpus 有一个自定义按钮,选中多个文件,然后点击按钮,弹出一个语言选项,选择确认后调用脚本。

首先先新建按钮,函数定义中的类型选择 标准功能(DOpus或外部程序),然后在下方的脚本编辑区域输入命令即可。如果是外部命令,会相当于用默认的终端执行。
所以,如果配置过 python 环境,我们是可以直接使用 python 命令的。

直接调用

python "{alias|script_py|noterm}/trans_text.py" -i {allfilepath$} -t "{dlgchoose|选择语言|default:简体中文=zh-CN+英语=en-US+日语=ja}"

拆解一下这条命令:

  • "{alias|script_py|noterm}/trans_text.py" 表示调用的脚本路径,前面用到了别名,其中 |noterm 是一个修饰符,表示去除路径最后的路径分隔符。
  • {allfilepath$}传递文件名代码,表示选中状态的所有文件完整路径,其中末尾的 $ 表示这个参数是必须的,如果为空,则不执行整条命令。
  • "{dlgchoose|选择语言|default:简体中文=zh-CN+英语=en-US+日语=ja}"对话框代码,允许在命令执行前,根据用户的输入获取参数。这里是弹出一个下拉对话框,内容是有默认值的语言列表。
    在执行命令前,可以把下方的 运行并记录日志 选中,这样控制台就会输出实际执行的命令,方便我们复制命令出来调试。

直接调用

如果我们不选中任何文件,直接点击运行。那么会发现控制台没有任何输出,因为我们上面使用了 {allfilepath$}
如果我们选中了文件,点击运行。会发现一闪而过一个黑色窗口,然后脚本目录下多了一个同名日志文件,内容应该是输入参数。这就说明我们调用脚本成功了。

控制状态

因为前面我们使用了 {allfilepath$} 来确保命令只有在选中文件时才会执行。但是其实我们还可以通过命令修饰符来控制按钮的可点击状态,这使得交互体验更加友好。

比如在脚本最上方增加命令 @disablenosel,表示 当未选择任何文件或文件夹时,将被禁用。保存后我们会发现,没有选中文件时,按钮变成灰色不可点击状态了。

@disablenosel
python "{alias|script_py|noterm}/trans_text.py" -i {allfilepath$} -t "{dlgchoose|选择语言|default:简体中文=zh-CN+英语=en-US+日语=ja}"

同理,还有 @hidenosel 表示 当未选择任何文件或文件夹时,将被隐藏

指定 Shell 和不关闭运行窗口

我们会发现,在点击按钮后,会打开一个终端窗口,然后执行脚本后再关闭。

有时候我们希望不关闭这个窗口,能够更方便我们查看执行结果。或者是希望通过指定的 Shell来运行脚本,比如 cmd 或 PowerShell。
可以用 cmd /k 命令powershell -NoExit -Command "& {命令}" 来实现脚本运行完毕后不关闭窗口。

需要注意的是:如果使用 PowerShell ,因为 -Command 命令是用双引号包裹的,因此内部实际执行命令的双引号是需要转义的。

我们的命令可能会变成以下形式,编写和调试脚本都会变得相当麻烦:

@disablenosel
powershell -NoExit -Command "& {python \"{alias|script_py|noterm}/trans_text.py\" -i \"{allfilepath$}\" -t \"zh_CN\" }"

为了避免转义,我们可以进行以下几个操作来减少转义:

  1. 利用设置局部变量命令 @set 设置一个变量,然后使用 {$变量名} 来引用
  2. 需要使用环境变量,可以使用语法 %环境变量名称%
  3. 指定PowerShell 并使用 -Command 参数时,命令中用单引号 ' 代替双引号 " 来包裹路径参数,动态参数通过 DOpus 的外部控制码或局部变量以及环境变量注入。

对于指定CMD 并且不关闭窗口来说,就变得很简单:

@disablenosel
@set user_dir=%USERPROFILE%
@set cmd_str = python "{alias|script_py|noterm}/trans_text.py" -i {allfilepath$} -t "{dlgchoose|选择语言|default:简体中文=zh-CN+英语=en-US+日语=ja}"
@output: user dir is :{$user_dir}
cmd /k {$cmd_str}

对于指定Powershell 并且不关闭窗口来说,需要注意转义问题:

  • 方案 1:将命令变量中包裹参数的双引号改成单引号,后面实际调用命令时用双引号包裹
@disablenosel
@set user_dir=%USERPROFILE%
@set cmd_str=python '{alias|script_py|noterm}/trans_text.py' -i '{allfilepath$}' -t '{dlgchoose|选择语言|default:简体中文=zh-CN+英语=en-US+日语=ja}'
@output: user dir is :{$user_dir}
powershell -NoExit -Command "& { {$cmd_str} }"
  • 方案 2:利用求值器进行替换
    这里利用到求值器语法 {=求值器表达式=} ,并使用 Replace函数 将变量 $cmd_str 中的双引号全部替换为单引号。
@disablenosel
@set user_dir=%USERPROFILE%
@set cmd_str=python "{alias|script_py|noterm}/trans_text.py" -i "{allfilepath$}" -t "{dlgchoose|选择语言|default:简体中文=zh-CN+英语=en-US+日语=ja}"
@output: user dir is :{$user_dir}
powershell -NoExit -Command "& { {=Replace($cmd_str,"""","'")=} }"

执行时隐藏窗口

如果不希望执行时终端一闪而过或者出现调用工具的界面,可以在上方增加一个运行模式的命令 @runmode:hide,表示运行时隐藏。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇