mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-08 14:34:13 +08:00
新增vm2,sleep函数调整,减少暴露给index的函数
This commit is contained in:
parent
210fba78ef
commit
48c161d45c
312
src/preload.js
312
src/preload.js
@ -1,61 +1,227 @@
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const { spawn, exec, execSync } = require("child_process")
|
||||
const child_process = require("child_process")
|
||||
const iconv = require('iconv-lite')
|
||||
const { clipboard } = require('electron')
|
||||
|
||||
const electron = require('electron')
|
||||
const { NodeVM } = require('vm2')
|
||||
const path = require("path")
|
||||
|
||||
pluginInfo = JSON.parse(fs.readFileSync(path.join(__dirname, 'plugin.json')));
|
||||
if (!utools.isWindows()) process.env.PATH += ':/usr/local/bin:/usr/local/sbin'
|
||||
|
||||
process.env.PATH += ':/usr/local/bin:/usr/local/sbin'
|
||||
const QuickCommandActions = [
|
||||
|
||||
window.require = require // 😈😈
|
||||
open = path => {
|
||||
utools.shellOpenItem(path)
|
||||
},
|
||||
|
||||
open = path => {
|
||||
utools.shellOpenItem(path)
|
||||
locate = path => {
|
||||
utools.shellShowItemInFolder(path);
|
||||
},
|
||||
|
||||
visit = url => {
|
||||
utools.shellOpenExternal(url);
|
||||
},
|
||||
|
||||
system = cmd => {
|
||||
return child_process.execSync(cmd);
|
||||
},
|
||||
|
||||
message = msg => {
|
||||
utools.showNotification(msg)
|
||||
},
|
||||
|
||||
keyTap = (key, ...modifier) => utools.simulateKeyboardTap(key, ...modifier),
|
||||
|
||||
simulateCopy = () => {
|
||||
var ctlKey = utools.isMacOs() ? 'command' : 'control';
|
||||
utools.simulateKeyboardTap('c', ctlKey);
|
||||
},
|
||||
|
||||
copyTo = text => {
|
||||
electron.clipboard.writeText(text)
|
||||
},
|
||||
|
||||
simulatePaste = () => {
|
||||
var ctlKey = utools.isMacOs() ? 'command' : 'control';
|
||||
utools.simulateKeyboardTap('v', ctlKey);
|
||||
},
|
||||
|
||||
send = text => {
|
||||
copyTo(text);
|
||||
simulatePaste();
|
||||
},
|
||||
|
||||
sleep = ms => {
|
||||
var start = new Date().getTime()
|
||||
var cmd, tempFilePath
|
||||
if (utools.isWindows()) {
|
||||
tempFilePath = getQuickCommandScriptFile('vbs')
|
||||
cmd = `echo set ws=CreateObject("Wscript.Shell") > ${tempFilePath} && echo Wscript.sleep ${ms} >> ${tempFilePath} && cscript /nologo ${tempFilePath}`
|
||||
} else {
|
||||
cmd = `sleep ${ms / 1000}`
|
||||
}
|
||||
try {
|
||||
child_process.execSync(cmd, { timeout: ms, })
|
||||
} catch (ex) {
|
||||
if (ex.code !== 'ETIMEDOUT') {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
var end = new Date().getTime()
|
||||
return (end - start)
|
||||
}
|
||||
]
|
||||
|
||||
var getSandboxFuns = () => {
|
||||
var sandbox = {
|
||||
utools: utools,
|
||||
process: process,
|
||||
electron: electron,
|
||||
fs: fs,
|
||||
path: path,
|
||||
os: os,
|
||||
child_process: child_process,
|
||||
alert: alert,
|
||||
$: {
|
||||
get: $.get,
|
||||
post: $.post,
|
||||
ajax: $.ajax
|
||||
}
|
||||
}
|
||||
QuickCommandActions.forEach(f => {
|
||||
sandbox[f.name] = f
|
||||
})
|
||||
return sandbox
|
||||
}
|
||||
|
||||
locate = path => {
|
||||
utools.shellShowItemInFolder(path);
|
||||
runCodeInVm = (cmd, cb) => {
|
||||
const vm = new NodeVM({
|
||||
require: {
|
||||
external: true,
|
||||
builtin: ["*"],
|
||||
},
|
||||
console: 'redirect',
|
||||
env: process.env,
|
||||
sandbox: getSandboxFuns()
|
||||
});
|
||||
|
||||
var parseItem = item => {
|
||||
if (typeof (item) == "object") {
|
||||
if (Buffer.isBuffer(item)) {
|
||||
var bufferString = `[Buffer ${item.slice(0, 50).toString('hex').match(/\w{1,2}/g).join(" ")}`
|
||||
if (item.length > 50) bufferString += `... ${(item.length/1000).toFixed(2)}kb`
|
||||
return bufferString + ']'
|
||||
} else {
|
||||
try {
|
||||
var cache = [];
|
||||
var string = JSON.stringify(item, (key, value) => {
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
if (cache.indexOf(value) !== -1) return
|
||||
cache.push(value);
|
||||
}
|
||||
return value;
|
||||
}, '\t')
|
||||
if (string != "{}") return string
|
||||
} catch (error) { }
|
||||
}
|
||||
} else if (typeof (item) == "undefined") {
|
||||
return "undefined"
|
||||
}
|
||||
return item.toString()
|
||||
}
|
||||
|
||||
var chunks = [], err_chunks = []
|
||||
|
||||
var callBackResult = () => {
|
||||
cb(chunks.join("\n"), err_chunks.join("\n"))
|
||||
}
|
||||
|
||||
vm.on('console.log', chunk => {
|
||||
console.log(chunk);
|
||||
chunks.push(parseItem(chunk))
|
||||
});
|
||||
|
||||
vm.on('console.error', err_chunk => {
|
||||
err_chunks.push(err_chunk.toString())
|
||||
});
|
||||
|
||||
var timer = setInterval(() => {
|
||||
if (process.exitcode == 1) {
|
||||
console.log('done');
|
||||
clearInterval(timer)
|
||||
callBackResult()
|
||||
}
|
||||
}, 100);
|
||||
|
||||
vm.run(`
|
||||
try {
|
||||
${cmd}
|
||||
} catch(e) {
|
||||
console.error(e)
|
||||
}
|
||||
process.exitcode = 1
|
||||
`, path.join(__dirname, 'preload.js'));
|
||||
}
|
||||
|
||||
visit = url => {
|
||||
utools.shellOpenExternal(url);
|
||||
// shell 以环境变量下命令作为代码提示
|
||||
getShellCommand = () => {
|
||||
var bin = []
|
||||
if (!utools.isWindows()) {
|
||||
process.env.PATH.split(':').forEach(d => {
|
||||
try {
|
||||
bin = bin.concat(fs.readdirSync(d).filter(x => x[0] != "."))
|
||||
} catch (e) { }
|
||||
})
|
||||
}
|
||||
return bin
|
||||
}
|
||||
|
||||
system = cmd => {
|
||||
return execSync(cmd);
|
||||
// cmd 以环境变量下命令作为代码提示
|
||||
getCmdCommand = () => {
|
||||
var bin = []
|
||||
if (utools.isWindows()) {
|
||||
process.env.Path.split(';').forEach(d => {
|
||||
try {
|
||||
bin = bin.concat(fs.readdirSync(d).filter(x => x.length > 4 && x.slice(-4) == '.exe'))
|
||||
} catch (e) { }
|
||||
})
|
||||
bin = bin.concat(bin).join("|").replace(/\.exe/g, '').split("|")
|
||||
}
|
||||
return bin
|
||||
}
|
||||
|
||||
message = msg => {
|
||||
utools.showNotification(msg)
|
||||
// NodeJs 代码提示
|
||||
getNodeJsCommand = () => {
|
||||
var obj = getSandboxFuns()
|
||||
obj.Buffer = Buffer
|
||||
return obj
|
||||
}
|
||||
|
||||
keyTap = utools.simulateKeyboardTap
|
||||
// isDev = /[a-zA-Z0-9\-]+\.asar/.test(__dirname) ? false : true
|
||||
// readFile = fs.readFileSync
|
||||
// writeFile = fs.writeFileSync
|
||||
// dirname = __dirname;
|
||||
// resolve = path.resolve;
|
||||
// tmpdir = os.tmpdir(),
|
||||
// exists = fs.existsSync;
|
||||
|
||||
sleep = ms => new Promise((r, j) => setTimeout(r, ms))
|
||||
|
||||
readFile = fs.readFileSync
|
||||
|
||||
writeFile = fs.writeFileSync
|
||||
|
||||
isWin = os.platform() == 'win32' ? true : false;
|
||||
|
||||
isDev = /[a-zA-Z0-9\-]+\.asar/.test(__dirname) ? false : true
|
||||
|
||||
basename = path.basename;
|
||||
dirname = __dirname;
|
||||
resolve = path.resolve;
|
||||
exists = fs.existsSync;
|
||||
tmpdir = os.tmpdir(),
|
||||
getQuickCommandScriptFile = ext => {
|
||||
return path.join(os.tmpdir(), `QuickCommandTempScript.${ext}`)
|
||||
}
|
||||
|
||||
getBase64Ico = path => {
|
||||
return fs.readFileSync(path, 'base64');
|
||||
}
|
||||
|
||||
openFolder = options => {
|
||||
return utools.showOpenDialog(options);
|
||||
openFileInDialog = (options, readfile) => {
|
||||
var file = utools.showOpenDialog(options)[0];
|
||||
if (!file) return false
|
||||
var information = {
|
||||
name: path.basename(file),
|
||||
path: file
|
||||
}
|
||||
if(readfile) information.data = fs.readFileSync(file)
|
||||
return information
|
||||
}
|
||||
|
||||
saveFile = (options, content) => {
|
||||
@ -65,45 +231,21 @@ saveFile = (options, content) => {
|
||||
})
|
||||
}
|
||||
|
||||
copy = () => {
|
||||
var ctlKey = isWin ? 'control' : 'command';
|
||||
utools.simulateKeyboardTap('c', ctlKey);
|
||||
}
|
||||
|
||||
copyTo = text => {
|
||||
clipboard.writeText(text)
|
||||
}
|
||||
|
||||
paste = () => {
|
||||
var ctlKey = isWin ? 'control' : 'command';
|
||||
utools.simulateKeyboardTap('v', ctlKey);
|
||||
}
|
||||
|
||||
send = text => {
|
||||
var historyData = storeClip();
|
||||
copyTo(text);
|
||||
paste();
|
||||
setTimeout(() => {
|
||||
restoreClip(historyData);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
|
||||
// 保存剪贴板
|
||||
storeClip = () => {
|
||||
var formats = clipboard.availableFormats("clipboard");
|
||||
var formats = electron.clipboard.availableFormats("clipboard");
|
||||
if (formats.includes("text/plain")) {
|
||||
return ['text', clipboard.readText()]
|
||||
return ['text', electron.clipboard.readText()]
|
||||
}
|
||||
if (formats.includes("image/png") || formats.includes("image/jpeg")) {
|
||||
return ['image', clipboard.readImage()]
|
||||
return ['image', electron.clipboard.readImage()]
|
||||
}
|
||||
var file;
|
||||
if (isWin) {
|
||||
file = clipboard.readBuffer('FileNameW').toString('ucs2').replace(/\\/g, '/');
|
||||
if (utools.isWindows()) {
|
||||
file = electron.clipboard.readBuffer('FileNameW').toString('ucs2').replace(/\\/g, '/');
|
||||
file = file.replace(new RegExp(String.fromCharCode(0), 'g'), '');
|
||||
} else {
|
||||
file = clipboard.read('public.file-url').replace('file://', '');
|
||||
file = electron.clipboard.read('public.file-url').replace('file://', '');
|
||||
}
|
||||
if (file) {
|
||||
return ['file', file]
|
||||
@ -114,25 +256,25 @@ storeClip = () => {
|
||||
// 恢复剪贴板
|
||||
restoreClip = historyData => {
|
||||
if (historyData[0] == 'text') {
|
||||
clipboard.writeText(historyData[1]);
|
||||
electron.clipboard.writeText(historyData[1]);
|
||||
return
|
||||
}
|
||||
if (historyData[0] == 'image') {
|
||||
clipboard.writeImage(historyData[1]);
|
||||
electron.clipboard.writeImage(historyData[1]);
|
||||
return
|
||||
}
|
||||
if (historyData[0] == 'file') {
|
||||
utools.copyFile(historyData[1])
|
||||
return
|
||||
}
|
||||
clipboard.writeText('')
|
||||
electron.clipboard.writeText('')
|
||||
}
|
||||
|
||||
getSelectText = () => {
|
||||
var historyData = storeClip();
|
||||
clipboard.writeText('');
|
||||
copy();
|
||||
var selectText = clipboard.readText()
|
||||
electron.clipboard.writeText('');
|
||||
simulateCopy();
|
||||
var selectText = electron.clipboard.readText()
|
||||
setTimeout(() => {
|
||||
restoreClip(historyData)
|
||||
}, 500);
|
||||
@ -141,9 +283,9 @@ getSelectText = () => {
|
||||
|
||||
getSelectFile = hwnd =>
|
||||
new Promise((reslove, reject) => {
|
||||
if (isWin) {
|
||||
if (utools.isWindows()) {
|
||||
var cmd = `powershell.exe -NoProfile "(New-Object -COM 'Shell.Application').Windows() | Where-Object { $_.HWND -eq ${hwnd} } | Select-Object -Expand Document | select @{ n='SelectItems'; e={$_.SelectedItems()} } | select -Expand SelectItems | select -Expand Path "`;
|
||||
exec(cmd, { encoding: "buffer" }, (err, stdout, stderr) => {
|
||||
child_process.exec(cmd, { encoding: "buffer" }, (err, stdout, stderr) => {
|
||||
if (err) reject(stderr)
|
||||
reslove(iconv.decode(stdout, 'GBK').trim().replace(/\\/g, '/'));
|
||||
})
|
||||
@ -157,7 +299,7 @@ getSelectFile = hwnd =>
|
||||
end repeat
|
||||
'
|
||||
`
|
||||
exec(cmd, (err, stdout, stderr) => {
|
||||
child_process.exec(cmd, (err, stdout, stderr) => {
|
||||
if (err) reject(stderr)
|
||||
reslove(stdout.trim());
|
||||
});
|
||||
@ -167,7 +309,7 @@ getSelectFile = hwnd =>
|
||||
special = cmd => {
|
||||
// 判断是否 windows 系统
|
||||
if (cmd.includes('{{isWin}}')) {
|
||||
let repl = isWin ? 1 : 0;
|
||||
let repl = utools.isWindows() ? 1 : 0;
|
||||
cmd = cmd.replace(/\{\{isWin\}\}/mg, repl)
|
||||
}
|
||||
|
||||
@ -185,7 +327,7 @@ special = cmd => {
|
||||
|
||||
// 获取剪切板的文本
|
||||
if (cmd.includes('{{ClipText}}')) {
|
||||
let repl = clipboard.readText();
|
||||
let repl = electron.clipboard.readText();
|
||||
cmd = cmd.replace(/\{\{ClipText\}\}/mg, repl)
|
||||
}
|
||||
|
||||
@ -197,11 +339,11 @@ special = cmd => {
|
||||
return cmd;
|
||||
}
|
||||
|
||||
run = (cmd, option, terminal, callback) => {
|
||||
runCodeFile = (cmd, option, terminal, callback) => {
|
||||
var bin = option.bin,
|
||||
argv = option.argv,
|
||||
ext = option.ext;
|
||||
let script = path.join(tmpdir, `QuickCommandTempScript.${ext}`)
|
||||
let script = getQuickCommandScriptFile(ext)
|
||||
// 批处理和 powershell 默认编码为 GBK, 解决批处理的换行问题
|
||||
if (ext == 'bat' || ext == 'ps1') cmd = iconv.encode(cmd.replace(/\n/g, '\r\n'), 'GBK');
|
||||
fs.writeFileSync(script, cmd);
|
||||
@ -214,9 +356,9 @@ run = (cmd, option, terminal, callback) => {
|
||||
if (bin) {
|
||||
// 在终端中输出
|
||||
if (terminal) {
|
||||
if (isWin) {
|
||||
child = spawn('cmd', ['/c', 'start', 'cmd', '/k', bin].concat(argvs), { encoding: 'buffer' })
|
||||
} else {
|
||||
if (utools.isWindows()) {
|
||||
child = child_process.spawn(`start cmd /k ${bin} ${argv} "${script}"`, { encoding: 'buffer', shell: true })
|
||||
} else if(utools.isMacOs()){
|
||||
var appleScript = `if application "Terminal" is running then
|
||||
tell application "Terminal"
|
||||
# do script without "in window" will open a new window
|
||||
@ -230,16 +372,18 @@ run = (cmd, option, terminal, callback) => {
|
||||
activate
|
||||
end tell
|
||||
end if`;
|
||||
child = spawn('osascript', ['-e', appleScript], { encoding: 'buffer' })
|
||||
child = child_process.spawn('osascript', ['-e', appleScript], { encoding: 'buffer' })
|
||||
} else {
|
||||
return utools.showNotification('Linux 不支持在终端输出')
|
||||
}
|
||||
} else {
|
||||
child = spawn(bin, argvs, { encoding: 'buffer' })
|
||||
child = child_process.spawn(bin, argvs, { encoding: 'buffer' })
|
||||
}
|
||||
} else {
|
||||
if (terminal) {
|
||||
child = spawn('cmd', ['/c', 'start', 'cmd', '/k', script], { encoding: 'buffer' })
|
||||
child = child_process.spawn(`start cmd /k "${script}"`, { encoding: 'buffer', shell: true })
|
||||
} else {
|
||||
child = spawn(script, { encoding: 'buffer' })
|
||||
child = child_process.spawn(script, { encoding: 'buffer' })
|
||||
}
|
||||
}
|
||||
var chunks = [],
|
||||
|
Loading…
x
Reference in New Issue
Block a user