oldj / node-font-list

Get the list of fonts installed in the system.
MIT License
133 stars 22 forks source link

关于fonts.vbs的建议 #25

Open similing4 opened 2 years ago

similing4 commented 2 years ago

建议直接在运行时判断文件是否存在,如果不存在则通过fs库将vbs内容写出到这个位置就好了

similing4 commented 2 years ago

我写了个例子:

const getFontScript = `Option Explicit

Dim objShell, objFSO, objFile, objFolder
Dim objFolderItem, colItems, objFont
Dim strFileName

Const FONTS = &H14& ' Fonts Folder

' Instantiate Objects
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(FONTS)
Set objFolderItem = objFolder.Self
Set colItems = objFolder.Items
Set objFSO = CreateObject("Scripting.FileSystemObject")

For Each objFont in colItems
    WScript.StdOut.WriteLine(objFont.Path & vbtab & objFont.Name)
Next

Set objShell = nothing
Set objFile = nothing
Set objFolder = nothing
Set objFolderItem = nothing
Set colItems = nothing
Set objFont = nothing
Set objFSO = nothing

wscript.quit`;
const fs = require('fs');
const path = require('path');
const execFile = require('child_process').execFile;
const iconv = require('iconv-lite');
const getFontsFromText = function(str) {
    let arr = str.split("\n");
    arr = arr.filter((r, ind) => {
        return ind > 2 && r.split("\t").length > 1;
    }).map((r) => {
        let res = r.trim()
            .split("\t");
        res[0] = res[0].split("\\")[res[0].split("\\").length - 1];
        res[1] = res[1].replace(/^\s+|\s+$/g, '')
            .replace(/(Regular|常规)$/i, '')
            .replace(/^\s+|\s+$/g, '');
        return {
            fontNickname: res[0],
            fontName: res[1]
        };
    });
    return arr;
};
module.exports = function() {
    return new Promise((recv, recj) => {
        const fontsVbsFile = path.resolve('./').replace(/\\/g, '/') + "/fonts.vbs";
        if (!fs.existsSync(fontsVbsFile))
            fs.writeSync(fontsVbsFile, getFontScript);
        execFile('cscript', [fontsVbsFile], {
            maxBuffer: 1024 * 1024 * 10,
            encoding: 'binary'
        }, (err, stdout, stderr) => {
            let fonts = []
            if (err) {
                recj(err)
                return
            }
            stdout = iconv.decode(Buffer.from(stdout, 'binary'), 'cp936');
            fonts = getFontsFromText(stdout);
            console.log(fonts);
            recv(fonts)
        });
    });
}
oldj commented 2 years ago

感谢建议。不过不是很明白,为什么需要这样处理呢? 目前已知 Electron 环境并且打包为 asar 的情况下,是无法直接执行这个 vbs 的,因此目前的代码中这种情况下会先将 vbs 写到临时目录再执行,还有其他场景需要这样操作吗?