mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-08 22:51:25 +08:00
新增vm2,sleep函数调整,减少暴露给index的函数
This commit is contained in:
parent
210fba78ef
commit
48c161d45c
304
src/preload.js
304
src/preload.js
@ -1,61 +1,227 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const os = require('os');
|
const os = require('os');
|
||||||
const { spawn, exec, execSync } = require("child_process")
|
const child_process = require("child_process")
|
||||||
const iconv = require('iconv-lite')
|
const iconv = require('iconv-lite')
|
||||||
const { clipboard } = require('electron')
|
const electron = require('electron')
|
||||||
|
const { NodeVM } = require('vm2')
|
||||||
const path = require("path")
|
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 => {
|
||||||
|
|
||||||
open = path => {
|
|
||||||
utools.shellOpenItem(path)
|
utools.shellOpenItem(path)
|
||||||
}
|
},
|
||||||
|
|
||||||
locate = path => {
|
locate = path => {
|
||||||
utools.shellShowItemInFolder(path);
|
utools.shellShowItemInFolder(path);
|
||||||
}
|
},
|
||||||
|
|
||||||
visit = url => {
|
visit = url => {
|
||||||
utools.shellOpenExternal(url);
|
utools.shellOpenExternal(url);
|
||||||
}
|
},
|
||||||
|
|
||||||
system = cmd => {
|
system = cmd => {
|
||||||
return execSync(cmd);
|
return child_process.execSync(cmd);
|
||||||
}
|
},
|
||||||
|
|
||||||
message = msg => {
|
message = msg => {
|
||||||
utools.showNotification(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
|
||||||
}
|
}
|
||||||
|
|
||||||
keyTap = utools.simulateKeyboardTap
|
runCodeInVm = (cmd, cb) => {
|
||||||
|
const vm = new NodeVM({
|
||||||
|
require: {
|
||||||
|
external: true,
|
||||||
|
builtin: ["*"],
|
||||||
|
},
|
||||||
|
console: 'redirect',
|
||||||
|
env: process.env,
|
||||||
|
sandbox: getSandboxFuns()
|
||||||
|
});
|
||||||
|
|
||||||
sleep = ms => new Promise((r, j) => setTimeout(r, ms))
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
readFile = fs.readFileSync
|
var chunks = [], err_chunks = []
|
||||||
|
|
||||||
writeFile = fs.writeFileSync
|
var callBackResult = () => {
|
||||||
|
cb(chunks.join("\n"), err_chunks.join("\n"))
|
||||||
|
}
|
||||||
|
|
||||||
isWin = os.platform() == 'win32' ? true : false;
|
vm.on('console.log', chunk => {
|
||||||
|
console.log(chunk);
|
||||||
|
chunks.push(parseItem(chunk))
|
||||||
|
});
|
||||||
|
|
||||||
isDev = /[a-zA-Z0-9\-]+\.asar/.test(__dirname) ? false : true
|
vm.on('console.error', err_chunk => {
|
||||||
|
err_chunks.push(err_chunk.toString())
|
||||||
|
});
|
||||||
|
|
||||||
basename = path.basename;
|
var timer = setInterval(() => {
|
||||||
dirname = __dirname;
|
if (process.exitcode == 1) {
|
||||||
resolve = path.resolve;
|
console.log('done');
|
||||||
exists = fs.existsSync;
|
clearInterval(timer)
|
||||||
tmpdir = os.tmpdir(),
|
callBackResult()
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
vm.run(`
|
||||||
|
try {
|
||||||
|
${cmd}
|
||||||
|
} catch(e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
process.exitcode = 1
|
||||||
|
`, path.join(__dirname, 'preload.js'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// NodeJs 代码提示
|
||||||
|
getNodeJsCommand = () => {
|
||||||
|
var obj = getSandboxFuns()
|
||||||
|
obj.Buffer = Buffer
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
getQuickCommandScriptFile = ext => {
|
||||||
|
return path.join(os.tmpdir(), `QuickCommandTempScript.${ext}`)
|
||||||
|
}
|
||||||
|
|
||||||
getBase64Ico = path => {
|
getBase64Ico = path => {
|
||||||
return fs.readFileSync(path, 'base64');
|
return fs.readFileSync(path, 'base64');
|
||||||
}
|
}
|
||||||
|
|
||||||
openFolder = options => {
|
openFileInDialog = (options, readfile) => {
|
||||||
return utools.showOpenDialog(options);
|
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) => {
|
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 = () => {
|
storeClip = () => {
|
||||||
var formats = clipboard.availableFormats("clipboard");
|
var formats = electron.clipboard.availableFormats("clipboard");
|
||||||
if (formats.includes("text/plain")) {
|
if (formats.includes("text/plain")) {
|
||||||
return ['text', clipboard.readText()]
|
return ['text', electron.clipboard.readText()]
|
||||||
}
|
}
|
||||||
if (formats.includes("image/png") || formats.includes("image/jpeg")) {
|
if (formats.includes("image/png") || formats.includes("image/jpeg")) {
|
||||||
return ['image', clipboard.readImage()]
|
return ['image', electron.clipboard.readImage()]
|
||||||
}
|
}
|
||||||
var file;
|
var file;
|
||||||
if (isWin) {
|
if (utools.isWindows()) {
|
||||||
file = clipboard.readBuffer('FileNameW').toString('ucs2').replace(/\\/g, '/');
|
file = electron.clipboard.readBuffer('FileNameW').toString('ucs2').replace(/\\/g, '/');
|
||||||
file = file.replace(new RegExp(String.fromCharCode(0), 'g'), '');
|
file = file.replace(new RegExp(String.fromCharCode(0), 'g'), '');
|
||||||
} else {
|
} else {
|
||||||
file = clipboard.read('public.file-url').replace('file://', '');
|
file = electron.clipboard.read('public.file-url').replace('file://', '');
|
||||||
}
|
}
|
||||||
if (file) {
|
if (file) {
|
||||||
return ['file', file]
|
return ['file', file]
|
||||||
@ -114,25 +256,25 @@ storeClip = () => {
|
|||||||
// 恢复剪贴板
|
// 恢复剪贴板
|
||||||
restoreClip = historyData => {
|
restoreClip = historyData => {
|
||||||
if (historyData[0] == 'text') {
|
if (historyData[0] == 'text') {
|
||||||
clipboard.writeText(historyData[1]);
|
electron.clipboard.writeText(historyData[1]);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (historyData[0] == 'image') {
|
if (historyData[0] == 'image') {
|
||||||
clipboard.writeImage(historyData[1]);
|
electron.clipboard.writeImage(historyData[1]);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (historyData[0] == 'file') {
|
if (historyData[0] == 'file') {
|
||||||
utools.copyFile(historyData[1])
|
utools.copyFile(historyData[1])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
clipboard.writeText('')
|
electron.clipboard.writeText('')
|
||||||
}
|
}
|
||||||
|
|
||||||
getSelectText = () => {
|
getSelectText = () => {
|
||||||
var historyData = storeClip();
|
var historyData = storeClip();
|
||||||
clipboard.writeText('');
|
electron.clipboard.writeText('');
|
||||||
copy();
|
simulateCopy();
|
||||||
var selectText = clipboard.readText()
|
var selectText = electron.clipboard.readText()
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
restoreClip(historyData)
|
restoreClip(historyData)
|
||||||
}, 500);
|
}, 500);
|
||||||
@ -141,9 +283,9 @@ getSelectText = () => {
|
|||||||
|
|
||||||
getSelectFile = hwnd =>
|
getSelectFile = hwnd =>
|
||||||
new Promise((reslove, reject) => {
|
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 "`;
|
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)
|
if (err) reject(stderr)
|
||||||
reslove(iconv.decode(stdout, 'GBK').trim().replace(/\\/g, '/'));
|
reslove(iconv.decode(stdout, 'GBK').trim().replace(/\\/g, '/'));
|
||||||
})
|
})
|
||||||
@ -157,7 +299,7 @@ getSelectFile = hwnd =>
|
|||||||
end repeat
|
end repeat
|
||||||
'
|
'
|
||||||
`
|
`
|
||||||
exec(cmd, (err, stdout, stderr) => {
|
child_process.exec(cmd, (err, stdout, stderr) => {
|
||||||
if (err) reject(stderr)
|
if (err) reject(stderr)
|
||||||
reslove(stdout.trim());
|
reslove(stdout.trim());
|
||||||
});
|
});
|
||||||
@ -167,7 +309,7 @@ getSelectFile = hwnd =>
|
|||||||
special = cmd => {
|
special = cmd => {
|
||||||
// 判断是否 windows 系统
|
// 判断是否 windows 系统
|
||||||
if (cmd.includes('{{isWin}}')) {
|
if (cmd.includes('{{isWin}}')) {
|
||||||
let repl = isWin ? 1 : 0;
|
let repl = utools.isWindows() ? 1 : 0;
|
||||||
cmd = cmd.replace(/\{\{isWin\}\}/mg, repl)
|
cmd = cmd.replace(/\{\{isWin\}\}/mg, repl)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +327,7 @@ special = cmd => {
|
|||||||
|
|
||||||
// 获取剪切板的文本
|
// 获取剪切板的文本
|
||||||
if (cmd.includes('{{ClipText}}')) {
|
if (cmd.includes('{{ClipText}}')) {
|
||||||
let repl = clipboard.readText();
|
let repl = electron.clipboard.readText();
|
||||||
cmd = cmd.replace(/\{\{ClipText\}\}/mg, repl)
|
cmd = cmd.replace(/\{\{ClipText\}\}/mg, repl)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,11 +339,11 @@ special = cmd => {
|
|||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
run = (cmd, option, terminal, callback) => {
|
runCodeFile = (cmd, option, terminal, callback) => {
|
||||||
var bin = option.bin,
|
var bin = option.bin,
|
||||||
argv = option.argv,
|
argv = option.argv,
|
||||||
ext = option.ext;
|
ext = option.ext;
|
||||||
let script = path.join(tmpdir, `QuickCommandTempScript.${ext}`)
|
let script = getQuickCommandScriptFile(ext)
|
||||||
// 批处理和 powershell 默认编码为 GBK, 解决批处理的换行问题
|
// 批处理和 powershell 默认编码为 GBK, 解决批处理的换行问题
|
||||||
if (ext == 'bat' || ext == 'ps1') cmd = iconv.encode(cmd.replace(/\n/g, '\r\n'), 'GBK');
|
if (ext == 'bat' || ext == 'ps1') cmd = iconv.encode(cmd.replace(/\n/g, '\r\n'), 'GBK');
|
||||||
fs.writeFileSync(script, cmd);
|
fs.writeFileSync(script, cmd);
|
||||||
@ -214,9 +356,9 @@ run = (cmd, option, terminal, callback) => {
|
|||||||
if (bin) {
|
if (bin) {
|
||||||
// 在终端中输出
|
// 在终端中输出
|
||||||
if (terminal) {
|
if (terminal) {
|
||||||
if (isWin) {
|
if (utools.isWindows()) {
|
||||||
child = spawn('cmd', ['/c', 'start', 'cmd', '/k', bin].concat(argvs), { encoding: 'buffer' })
|
child = child_process.spawn(`start cmd /k ${bin} ${argv} "${script}"`, { encoding: 'buffer', shell: true })
|
||||||
} else {
|
} else if(utools.isMacOs()){
|
||||||
var appleScript = `if application "Terminal" is running then
|
var appleScript = `if application "Terminal" is running then
|
||||||
tell application "Terminal"
|
tell application "Terminal"
|
||||||
# do script without "in window" will open a new window
|
# do script without "in window" will open a new window
|
||||||
@ -230,16 +372,18 @@ run = (cmd, option, terminal, callback) => {
|
|||||||
activate
|
activate
|
||||||
end tell
|
end tell
|
||||||
end if`;
|
end if`;
|
||||||
child = spawn('osascript', ['-e', appleScript], { encoding: 'buffer' })
|
child = child_process.spawn('osascript', ['-e', appleScript], { encoding: 'buffer' })
|
||||||
|
} else {
|
||||||
|
return utools.showNotification('Linux 不支持在终端输出')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
child = spawn(bin, argvs, { encoding: 'buffer' })
|
child = child_process.spawn(bin, argvs, { encoding: 'buffer' })
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (terminal) {
|
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 {
|
} else {
|
||||||
child = spawn(script, { encoding: 'buffer' })
|
child = child_process.spawn(script, { encoding: 'buffer' })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var chunks = [],
|
var chunks = [],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user