optimize the opening item logic (solve the problem that some software/files cannot be opened, and too many running programs cause the program to crash).

This commit is contained in:
unknown 2024-04-10 21:12:28 +08:00
parent 480f88d558
commit 6b71805274
5 changed files with 146 additions and 145 deletions

View File

@ -11,6 +11,7 @@ import {
} from ".";
import { statSync } from "node:fs";
import { getWindow } from "../commons/index";
import { execute } from "../item";
export default function () {
// emit
@ -165,7 +166,7 @@ export default function () {
});
// 运行
ipcMain.on("run", (event, args) => {
global.addon.shellExecute(
execute(
args.operation,
args.target,
args.params ?? "",

View File

@ -1,5 +1,5 @@
import { BrowserWindow, shell, dialog, app } from "electron";
import { join } from "node:path";
import { join, dirname } from "node:path";
import { parsePath, getURLParams } from "../../commons/utils";
import { Item } from "../../../types/item";
import {
@ -11,7 +11,7 @@ import {
updateData,
updateOrder,
} from "./data";
import { accessSync, writeFile, statSync, readFileSync } from "node:fs";
import { writeFile, statSync, readFileSync } from "node:fs";
import mime from "mime";
import {
deleteExtname,
@ -27,6 +27,7 @@ import {
sendToWebContent,
} from "../commons/index";
import { fork } from "../../commons/utilityProcessUtils";
import { exec } from "node:child_process";
// 窗口
let itemAddEditWindow: BrowserWindow | null = null;
@ -301,6 +302,58 @@ function updateOpenInfo(type: string, id: number) {
}
}
/**
*
* @param operation
* @param file
* @param params
* @param startLocation
*/
function execute(
operation: "open" | "runas",
file: string,
params: string | null,
startLocation: string | null = null
) {
// 工作目录
let currentDir = startLocation;
if (!currentDir || currentDir.trim() === "") {
let statRes = statSync(file);
if (statRes.isDirectory()) {
currentDir = file;
} else {
currentDir = dirname(file);
}
}
// 组装命令
let cmd: string;
if (operation === "open") {
cmd = 'start "" "' + file + '"';
if (params && params.trim() !== "") {
let paramsList = analysisParams(params);
for (const param of paramsList) {
cmd += ' "' + param + '"';
}
}
} else if (operation === "runas") {
cmd = "powershell Start-Process";
cmd += " '\"" + file + "\"' ";
cmd += "-Verb RunAs";
if (params && params.trim() !== "") {
cmd += " -ArgumentList ";
let paramsList = analysisParams(params);
for (let i = 0; i < paramsList.length; i++) {
if (i > 0) {
cmd += ", ";
}
cmd += "'\\\"" + paramsList[i] + "\\\"'";
}
}
}
// 运行
exec(cmd, { cwd: currentDir });
}
/**
*
* @param type
@ -320,50 +373,88 @@ function run(
// 网址
shell.openExternal(item.data.target);
} else if (item.type === 3 || item.type === 4) {
// 系统 或 appx
global.addon.systemItemExecute(item.data.target, item.data.params);
if (item.data.target.indexOf("shell:") >= 0) {
// 带有shell:
exec("explorer " + item.data.target);
} else if (item.data.target === "static:TurnOffMonitor") {
// 关闭显示器
global.addon.turnOffMonitor();
} else {
if (item.type === 3) {
// 带路径的系统软件
let path = global.addon.searchPath(item.data.target);
if (!path || path.trim() === "") {
path = item.data.target;
}
let cmd = 'start "" "' + path + '"';
if (item.data.params && item.data.params.trim() !== "") {
let paramsList = analysisParams(item.data.params);
for (const param of paramsList) {
cmd += ' "' + param + '"';
}
}
exec(cmd, {
cwd: app.getPath("home"),
});
} else {
// appx
execute(
"open",
item.data.target,
item.data.params,
app.getPath("home")
);
}
}
} else {
// 获取绝对路径
if (item.type === 0 || item.type === 1) {
// 获取路径
item.data.target = parsePath(item.data.target);
}
try {
// 判断文件或文件夹是否存在
accessSync(item.data.target);
// 存在
if (operation === "openFileLocation") {
// 打开文件所在位置
global.addon.openFileLocation(item.data.target);
} else {
// 运行
global.addon.shellExecute(
operation,
item.data.target,
item.data.params ?? "",
item.data.startLocation
);
}
} catch (e) {
let message: string | null = null;
if (item.type === 0 && operation !== "openFileLocation") {
message = global.language.notFoundFile;
} else {
message = global.language.notFoundFolder;
}
message += '"' + item.data.target + '"';
dialog.showMessageBox(global.mainWindow, {
title: "Dawn Launcher",
message: message,
buttons: [global.language.ok],
type: "error",
noLink: true,
});
if (operation === "openFileLocation") {
// 打开文件所在位置
global.addon.openFileLocation(item.data.target);
} else {
// 运行
execute(
operation,
item.data.target,
item.data.params ?? "",
item.data.startLocation
);
}
}
}
}
/**
*
* @param params
*/
function analysisParams(params: string) {
// res
let resParams = [];
// 尝试获取带有双引号的参数
const values = params.trim().match(/"([^"]*)"/g);
// 添加到结果列表并替换掉原有字符串
if (values) {
values.forEach((v) => {
resParams.push(v.replace(/"/g, ""));
params = params.replace(v, "");
});
}
// 按空格切分参数
let split = params.trim().split(" ");
split.forEach((v) => {
if (v.trim() !== "") {
resParams.push(v);
}
});
// 返回
return resParams;
}
/**
*
* @param idList
@ -711,4 +802,5 @@ export {
pasteIcon,
checkInvalid,
deleteQuickSearchHistory,
execute,
};

View File

@ -31,24 +31,6 @@ fn get_shortcut_file_info(path: String) -> Option<HashMap<String, String>> {
windows::get_shortcut_file_info(&path)
}
/**
*
*/
#[allow(dead_code)]
#[napi]
fn shell_execute(operation: String, file: String, params: String, start_location: Option<String>) {
windows::shell_execute(operation, file, params, start_location)
}
/**
*
*/
#[allow(dead_code)]
#[napi]
fn system_item_execute(target: String, params: Option<String>) {
windows::system_item_execute(&target, params.as_deref())
}
/**
*
*/
@ -192,3 +174,12 @@ fn get_appx_list() -> Vec<HashMap<String, String>> {
fn get_cursor_point() -> [i32; 2] {
windows::get_cursor_point()
}
/**
*
*/
#[allow(dead_code)]
#[napi]
pub fn turn_off_monitor() {
windows::turn_off_monitor()
}

View File

@ -6,18 +6,15 @@ use napi::{
JsFunction,
};
use serde::{Deserialize, Serialize};
use std::thread;
use std::{
collections::HashMap,
io::Cursor,
path::Path,
process::Command,
sync::atomic::{AtomicBool, Ordering},
};
use windows::Management::Deployment::PackageManager;
use windows::{
core::{ComInterface, HSTRING, PCSTR, PCWSTR},
w,
Win32::{
Foundation::{HWND, LPARAM, LRESULT, MAX_PATH, POINT, RECT, SIZE, WPARAM},
Graphics::{
@ -34,7 +31,6 @@ use windows::{
CLSCTX_INPROC_SERVER, COINIT_APARTMENTTHREADED, STGM_READ,
},
Environment::GetEnvironmentVariableW,
SystemInformation::GetSystemDirectoryW,
},
UI::{
Input::Ime::{
@ -44,19 +40,18 @@ use windows::{
Shell::{
BHID_SFUIObject, IContextMenu, IShellItem, IShellItemImageFactory, IShellLinkW,
SHCreateItemFromParsingName, SHEmptyRecycleBinW, SHQueryUserNotificationState,
ShellExecuteW, ShellLink, CMF_NORMAL, CMINVOKECOMMANDINFO,
QUNS_ACCEPTS_NOTIFICATIONS, QUNS_APP, QUNS_BUSY, QUNS_NOT_PRESENT,
QUNS_PRESENTATION_MODE, QUNS_QUIET_TIME, QUNS_RUNNING_D3D_FULL_SCREEN,
SHERB_NOSOUND, SIIGBF_ICONONLY, SLGP_UNCPRIORITY,
ShellLink, CMF_NORMAL, CMINVOKECOMMANDINFO, QUNS_ACCEPTS_NOTIFICATIONS, QUNS_APP,
QUNS_BUSY, QUNS_NOT_PRESENT, QUNS_PRESENTATION_MODE, QUNS_QUIET_TIME,
QUNS_RUNNING_D3D_FULL_SCREEN, SHERB_NOSOUND, SIIGBF_ICONONLY, SLGP_UNCPRIORITY,
},
WindowsAndMessaging::{
CallNextHookEx, CreatePopupMenu, DestroyMenu, FindWindowW, GetClassNameW,
GetCursorPos, GetForegroundWindow, GetSystemMetrics, GetWindowRect, SendMessageW,
SetForegroundWindow, SetWindowsHookExW, TrackPopupMenu, WindowFromPoint, HHOOK,
MSLLHOOKSTRUCT, SC_MONITORPOWER, SM_CXSCREEN, SM_CYSCREEN, SW_NORMAL,
SW_SHOWDEFAULT, TPM_NONOTIFY, TPM_RETURNCMD, WH_MOUSE_LL, WM_LBUTTONDOWN,
WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MOUSEHWHEEL, WM_MOUSEMOVE,
WM_MOUSEWHEEL, WM_RBUTTONDOWN, WM_RBUTTONUP, WM_SYSCOMMAND,
MSLLHOOKSTRUCT, SC_MONITORPOWER, SM_CXSCREEN, SM_CYSCREEN, SW_NORMAL, TPM_NONOTIFY,
TPM_RETURNCMD, WH_MOUSE_LL, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN,
WM_MBUTTONUP, WM_MOUSEHWHEEL, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_RBUTTONDOWN,
WM_RBUTTONUP, WM_SYSCOMMAND,
},
},
},
@ -177,45 +172,6 @@ fn image_buffer_to_base64(image_buffer: ImageBuffer<Rgba<u8>, Vec<u8>>) -> Strin
)
}
/**
*
*/
pub fn shell_execute(
operation: String,
file: String,
params: String,
start_location: Option<String>,
) {
thread::spawn(move || {
// dir
let dir = start_location.unwrap_or_else(|| {
// 判断是否是文件夹
let path = Path::new(&file);
if path.is_dir() {
// 文件夹
file.clone()
} else {
// 文件 获取上一级目录
path.parent().unwrap().display().to_string()
}
});
// HSTRING
let operation = HSTRING::from(operation.as_str());
let file = HSTRING::from(file.as_str());
let params = HSTRING::from(params.as_str());
let dir = HSTRING::from(dir.as_str());
// PCWSTR
let operation = PCWSTR(operation.as_ptr());
let file = PCWSTR(file.as_ptr());
let params = PCWSTR(params.as_ptr());
let dir = PCWSTR(dir.as_ptr());
unsafe {
// execute
ShellExecuteW(None, operation, file, params, dir, SW_SHOWDEFAULT);
}
});
}
/**
*
*/
@ -265,45 +221,6 @@ pub fn get_shortcut_file_info(path: &str) -> Option<HashMap<String, String>> {
None
}
/**
*
*/
pub fn system_item_execute(target: &str, params: Option<&str>) {
if target == "static:TurnOffMonitor" {
// 关闭显示器
turn_off_monitor()
} else {
let mut file = target.to_string();
if !target.starts_with("shell:") {
// 如果不是shell开头就查询路径
file = search_path(target).unwrap_or(target.to_string());
}
let file = HSTRING::from(file);
let params = match params {
Some(p) => HSTRING::from(p),
_ => HSTRING::new(),
};
// 获取系统盘路径当作工作目录
let mut buffer = [0u16; MAX_PATH as usize];
unsafe {
GetSystemDirectoryW(Some(&mut buffer));
}
let dir = u16_to_string(&buffer);
let dir = HSTRING::from(dir);
// execute
unsafe {
ShellExecuteW(
None,
w!("open"),
PCWSTR(file.as_ptr()),
PCWSTR(params.as_ptr()),
PCWSTR(dir.as_ptr()),
SW_SHOWDEFAULT,
);
}
}
}
/**
*
*/

View File

@ -536,7 +536,7 @@ function drop(e: any, classificationId: number | null) {
) {
// 使
if (item.id !== store.itemDragOutData.id) {
let params = store.itemDragOutData.data.target;
let params = '"' + store.itemDragOutData.data.target + '"';
if (item.data.params) {
params += " " + item.data.params;
}