mirror of
https://github.com/fanchenio/DawnLauncher.git
synced 2025-07-14 05:12:11 +08:00
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:
parent
480f88d558
commit
6b71805274
@ -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 ?? "",
|
||||
|
@ -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,
|
||||
};
|
||||
|
27
rust/lib.rs
27
rust/lib.rs
@ -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()
|
||||
}
|
||||
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭显示器
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user