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 ".";
|
} from ".";
|
||||||
import { statSync } from "node:fs";
|
import { statSync } from "node:fs";
|
||||||
import { getWindow } from "../commons/index";
|
import { getWindow } from "../commons/index";
|
||||||
|
import { execute } from "../item";
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
// emit
|
// emit
|
||||||
@ -165,7 +166,7 @@ export default function () {
|
|||||||
});
|
});
|
||||||
// 运行
|
// 运行
|
||||||
ipcMain.on("run", (event, args) => {
|
ipcMain.on("run", (event, args) => {
|
||||||
global.addon.shellExecute(
|
execute(
|
||||||
args.operation,
|
args.operation,
|
||||||
args.target,
|
args.target,
|
||||||
args.params ?? "",
|
args.params ?? "",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { BrowserWindow, shell, dialog, app } from "electron";
|
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 { parsePath, getURLParams } from "../../commons/utils";
|
||||||
import { Item } from "../../../types/item";
|
import { Item } from "../../../types/item";
|
||||||
import {
|
import {
|
||||||
@ -11,7 +11,7 @@ import {
|
|||||||
updateData,
|
updateData,
|
||||||
updateOrder,
|
updateOrder,
|
||||||
} from "./data";
|
} from "./data";
|
||||||
import { accessSync, writeFile, statSync, readFileSync } from "node:fs";
|
import { writeFile, statSync, readFileSync } from "node:fs";
|
||||||
import mime from "mime";
|
import mime from "mime";
|
||||||
import {
|
import {
|
||||||
deleteExtname,
|
deleteExtname,
|
||||||
@ -27,6 +27,7 @@ import {
|
|||||||
sendToWebContent,
|
sendToWebContent,
|
||||||
} from "../commons/index";
|
} from "../commons/index";
|
||||||
import { fork } from "../../commons/utilityProcessUtils";
|
import { fork } from "../../commons/utilityProcessUtils";
|
||||||
|
import { exec } from "node:child_process";
|
||||||
|
|
||||||
// 窗口
|
// 窗口
|
||||||
let itemAddEditWindow: BrowserWindow | null = null;
|
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
|
* @param type
|
||||||
@ -320,50 +373,88 @@ function run(
|
|||||||
// 网址
|
// 网址
|
||||||
shell.openExternal(item.data.target);
|
shell.openExternal(item.data.target);
|
||||||
} else if (item.type === 3 || item.type === 4) {
|
} else if (item.type === 3 || item.type === 4) {
|
||||||
// 系统 或 appx
|
if (item.data.target.indexOf("shell:") >= 0) {
|
||||||
global.addon.systemItemExecute(item.data.target, item.data.params);
|
// 带有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 {
|
} else {
|
||||||
// 获取绝对路径
|
// 获取绝对路径
|
||||||
if (item.type === 0 || item.type === 1) {
|
if (item.type === 0 || item.type === 1) {
|
||||||
// 获取路径
|
// 获取路径
|
||||||
item.data.target = parsePath(item.data.target);
|
item.data.target = parsePath(item.data.target);
|
||||||
}
|
}
|
||||||
try {
|
if (operation === "openFileLocation") {
|
||||||
// 判断文件或文件夹是否存在
|
// 打开文件所在位置
|
||||||
accessSync(item.data.target);
|
global.addon.openFileLocation(item.data.target);
|
||||||
// 存在
|
} else {
|
||||||
if (operation === "openFileLocation") {
|
// 运行
|
||||||
// 打开文件所在位置
|
execute(
|
||||||
global.addon.openFileLocation(item.data.target);
|
operation,
|
||||||
} else {
|
item.data.target,
|
||||||
// 运行
|
item.data.params ?? "",
|
||||||
global.addon.shellExecute(
|
item.data.startLocation
|
||||||
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,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析参数
|
||||||
|
* @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
|
* @param idList
|
||||||
@ -711,4 +802,5 @@ export {
|
|||||||
pasteIcon,
|
pasteIcon,
|
||||||
checkInvalid,
|
checkInvalid,
|
||||||
deleteQuickSearchHistory,
|
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)
|
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] {
|
fn get_cursor_point() -> [i32; 2] {
|
||||||
windows::get_cursor_point()
|
windows::get_cursor_point()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭显示器
|
||||||
|
*/
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[napi]
|
||||||
|
pub fn turn_off_monitor() {
|
||||||
|
windows::turn_off_monitor()
|
||||||
|
}
|
||||||
|
@ -6,18 +6,15 @@ use napi::{
|
|||||||
JsFunction,
|
JsFunction,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::thread;
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
io::Cursor,
|
io::Cursor,
|
||||||
path::Path,
|
|
||||||
process::Command,
|
process::Command,
|
||||||
sync::atomic::{AtomicBool, Ordering},
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
};
|
};
|
||||||
use windows::Management::Deployment::PackageManager;
|
use windows::Management::Deployment::PackageManager;
|
||||||
use windows::{
|
use windows::{
|
||||||
core::{ComInterface, HSTRING, PCSTR, PCWSTR},
|
core::{ComInterface, HSTRING, PCSTR, PCWSTR},
|
||||||
w,
|
|
||||||
Win32::{
|
Win32::{
|
||||||
Foundation::{HWND, LPARAM, LRESULT, MAX_PATH, POINT, RECT, SIZE, WPARAM},
|
Foundation::{HWND, LPARAM, LRESULT, MAX_PATH, POINT, RECT, SIZE, WPARAM},
|
||||||
Graphics::{
|
Graphics::{
|
||||||
@ -34,7 +31,6 @@ use windows::{
|
|||||||
CLSCTX_INPROC_SERVER, COINIT_APARTMENTTHREADED, STGM_READ,
|
CLSCTX_INPROC_SERVER, COINIT_APARTMENTTHREADED, STGM_READ,
|
||||||
},
|
},
|
||||||
Environment::GetEnvironmentVariableW,
|
Environment::GetEnvironmentVariableW,
|
||||||
SystemInformation::GetSystemDirectoryW,
|
|
||||||
},
|
},
|
||||||
UI::{
|
UI::{
|
||||||
Input::Ime::{
|
Input::Ime::{
|
||||||
@ -44,19 +40,18 @@ use windows::{
|
|||||||
Shell::{
|
Shell::{
|
||||||
BHID_SFUIObject, IContextMenu, IShellItem, IShellItemImageFactory, IShellLinkW,
|
BHID_SFUIObject, IContextMenu, IShellItem, IShellItemImageFactory, IShellLinkW,
|
||||||
SHCreateItemFromParsingName, SHEmptyRecycleBinW, SHQueryUserNotificationState,
|
SHCreateItemFromParsingName, SHEmptyRecycleBinW, SHQueryUserNotificationState,
|
||||||
ShellExecuteW, ShellLink, CMF_NORMAL, CMINVOKECOMMANDINFO,
|
ShellLink, CMF_NORMAL, CMINVOKECOMMANDINFO, QUNS_ACCEPTS_NOTIFICATIONS, QUNS_APP,
|
||||||
QUNS_ACCEPTS_NOTIFICATIONS, QUNS_APP, QUNS_BUSY, QUNS_NOT_PRESENT,
|
QUNS_BUSY, QUNS_NOT_PRESENT, QUNS_PRESENTATION_MODE, QUNS_QUIET_TIME,
|
||||||
QUNS_PRESENTATION_MODE, QUNS_QUIET_TIME, QUNS_RUNNING_D3D_FULL_SCREEN,
|
QUNS_RUNNING_D3D_FULL_SCREEN, SHERB_NOSOUND, SIIGBF_ICONONLY, SLGP_UNCPRIORITY,
|
||||||
SHERB_NOSOUND, SIIGBF_ICONONLY, SLGP_UNCPRIORITY,
|
|
||||||
},
|
},
|
||||||
WindowsAndMessaging::{
|
WindowsAndMessaging::{
|
||||||
CallNextHookEx, CreatePopupMenu, DestroyMenu, FindWindowW, GetClassNameW,
|
CallNextHookEx, CreatePopupMenu, DestroyMenu, FindWindowW, GetClassNameW,
|
||||||
GetCursorPos, GetForegroundWindow, GetSystemMetrics, GetWindowRect, SendMessageW,
|
GetCursorPos, GetForegroundWindow, GetSystemMetrics, GetWindowRect, SendMessageW,
|
||||||
SetForegroundWindow, SetWindowsHookExW, TrackPopupMenu, WindowFromPoint, HHOOK,
|
SetForegroundWindow, SetWindowsHookExW, TrackPopupMenu, WindowFromPoint, HHOOK,
|
||||||
MSLLHOOKSTRUCT, SC_MONITORPOWER, SM_CXSCREEN, SM_CYSCREEN, SW_NORMAL,
|
MSLLHOOKSTRUCT, SC_MONITORPOWER, SM_CXSCREEN, SM_CYSCREEN, SW_NORMAL, TPM_NONOTIFY,
|
||||||
SW_SHOWDEFAULT, TPM_NONOTIFY, TPM_RETURNCMD, WH_MOUSE_LL, WM_LBUTTONDOWN,
|
TPM_RETURNCMD, WH_MOUSE_LL, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN,
|
||||||
WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MOUSEHWHEEL, WM_MOUSEMOVE,
|
WM_MBUTTONUP, WM_MOUSEHWHEEL, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_RBUTTONDOWN,
|
||||||
WM_MOUSEWHEEL, WM_RBUTTONDOWN, WM_RBUTTONUP, WM_SYSCOMMAND,
|
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
|
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) {
|
if (item.id !== store.itemDragOutData.id) {
|
||||||
let params = store.itemDragOutData.data.target;
|
let params = '"' + store.itemDragOutData.data.target + '"';
|
||||||
if (item.data.params) {
|
if (item.data.params) {
|
||||||
params += " " + item.data.params;
|
params += " " + item.data.params;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user