Compare commits

...

14 Commits
1.4.7 ... main

15 changed files with 279 additions and 249 deletions

View File

@ -561,6 +561,13 @@ function showOpenDialogSync(windowName: string, options: OpenDialogOptions) {
return pathList; return pathList;
} }
/**
*
*/
function mainWindowExist() {
return global.mainWindow && !global.mainWindow.isDestroyed();
}
export { export {
downloadImage, downloadImage,
getURLInfo, getURLInfo,
@ -580,4 +587,5 @@ export {
showErrorMessageBox, showErrorMessageBox,
showSaveDialogSync, showSaveDialogSync,
showOpenDialogSync, showOpenDialogSync,
mainWindowExist,
}; };

View File

@ -332,9 +332,9 @@ function batchDel(idList: Array<number>) {
// 参数 // 参数
let params = itemList.map((item) => item.id).join(","); let params = itemList.map((item) => item.id).join(",");
// SQL // SQL
let sql = `DELETE FROM ${tableName} WHERE id in (?)`; let sql = `DELETE FROM ${tableName} WHERE id in (${params})`;
// 运行 // 运行
let res = db.prepare(sql).run(params).changes > 0; let res = db.prepare(sql).run().changes > 0;
if (res) { if (res) {
// 提取分类ID // 提取分类ID
let classificationIdList = new Set<number>(); let classificationIdList = new Set<number>();

View File

@ -1,6 +1,6 @@
import { BrowserWindow, shell, app } from "electron"; import { BrowserWindow, shell, app } from "electron";
import { join } from "node:path"; import { extname, join } from "node:path";
import { parsePath, getURLParams } from "../../commons/utils"; import { parsePath, getURLParams, getFileIcon } from "../../commons/utils";
import { Item } from "../../../types/item"; import { Item } from "../../../types/item";
import { import {
batchAdd, batchAdd,
@ -15,8 +15,10 @@ import { writeFile, statSync, readFileSync, accessSync } from "node:fs";
import mime from "mime"; import mime from "mime";
import { import {
deleteExtname, deleteExtname,
getFileName,
getItemName, getItemName,
isAbsolutePath, isAbsolutePath,
newItem,
} from "../../../commons/utils/common"; } from "../../../commons/utils/common";
import { iconExts } from "../../commons/utils"; import { iconExts } from "../../commons/utils";
import { addAssociateFolderWatcher } from "../classification"; import { addAssociateFolderWatcher } from "../classification";
@ -29,6 +31,7 @@ import {
showSaveDialogSync, showSaveDialogSync,
} from "../commons/index"; } from "../commons/index";
import { fork } from "../../commons/utilityProcessUtils"; import { fork } from "../../commons/utilityProcessUtils";
import { ShortcutInfo } from "../../../types/common";
// 窗口 // 窗口
let itemAddEditWindow: BrowserWindow | null = null; let itemAddEditWindow: BrowserWindow | null = null;
@ -260,24 +263,17 @@ function move(idList: Array<number>, toClassificationId: number) {
* @param classificationId * @param classificationId
* @param pathList * @param pathList
*/ */
function drop(classificationId: number, pathList: Array<string>) { async function drop(classificationId: number, pathList: Array<string>) {
fork( // 获取项目信息
"getDropItemInfo", let resultList = await getDropItemInfo(classificationId, pathList);
{ // 添加项目
classificationId, let itemList = batchAdd(classificationId, resultList);
pathList, // 发送消息到页面
}, sendToWebContent("mainWindow", "onAddItem", {
(resultList: Array<Item>) => { itemList,
// 添加项目 clear: false,
let itemList = batchAdd(classificationId, resultList); classificationId: null,
// 发送消息到页面 });
sendToWebContent("mainWindow", "onAddItem", {
itemList,
clear: false,
classificationId: null,
});
}
);
} }
/** /**
@ -323,10 +319,15 @@ function updateOpenInfo(type: string, id: number) {
*/ */
function run( function run(
type: string, type: string,
operation: "open" | "runas" | "openFileLocation", operation: "open" | "runas" | "openFileLocation" | "explore",
item: Item item: Item
) { ) {
if (item.data) { if (item.data) {
if (operation === "open" && item.data.runAsAdmin) {
operation = "runas";
} else if (operation === "open" && item.type === 1) {
operation = "explore";
}
// 更新打开信息 // 更新打开信息
updateOpenInfo(type, item.id); updateOpenInfo(type, item.id);
// 判断类型 // 判断类型
@ -703,6 +704,90 @@ function deleteQuickSearchHistory(itemId: number) {
} }
} }
/**
*
* @param classificationId
* @param pathList
*/
async function getDropItemInfo(
classificationId: number,
pathList: Array<string>
) {
// 项目列表
let itemList: Array<Item> = [];
// 解析文件信息并添加项目
for (const path of pathList) {
try {
// item
let item = newItem({ classificationId });
// 目标
item.data.target = path;
// 名称
item.name = getFileName(item.data.target);
// 判断是否是快捷方式,如果是的话,需要获取真实路径
if (mime.getType(path) === "application/x-ms-shortcut") {
// 快捷方式
// 获取真实文件路径和参数
let shortcutInfo: ShortcutInfo | null =
global.addon.getShortcutFileInfo(path);
if (shortcutInfo) {
// 路径
if (shortcutInfo.target) {
item.data.target = shortcutInfo.target;
}
// 参数
if (shortcutInfo.arguments) {
item.data.params = shortcutInfo.arguments;
}
}
}
// 获取图标
item.data.icon = await getFileIcon(item.data.target);
// 获取后缀判断是否是url
let ext = extname(item.data.target);
if (ext && ext.toLowerCase() === ".url") {
// url
let url = parseUrlFileContent(readFileSync(item.data.target, "utf-8"));
if (url && url.trim() !== "") {
item.data.target = url;
item.type = 2;
} else {
continue;
}
} else {
// 文件类型
let stats = statSync(item.data.target);
item.type = stats.isFile() ? 0 : 1;
}
// 去掉后缀
if (item.type === 0 || item.type === 2) {
item.name = deleteExtname(item.name);
}
// push
itemList.push(item);
} catch (e) {}
}
return itemList;
}
/**
* .url文件内容以获取URL
* @param content
* @returns
*/
function parseUrlFileContent(content: string) {
if (content) {
const lines = content.split("\n");
for (const line of lines) {
if (line.startsWith("URL=")) {
const url = line.substring(4).trim();
return url;
}
}
}
return null;
}
export { export {
createAddEditWindow, createAddEditWindow,
createNetworkIconWindow, createNetworkIconWindow,

View File

@ -203,8 +203,7 @@ export default function () {
// "打开"菜单 // "打开"菜单
let openMenu = false; let openMenu = false;
if ( if (
(item.type === 0 && item.type === 0 ||
global.addon.hasRunas(parsePath(item.data.target))) ||
item.type === 4 || item.type === 4 ||
(item.type === 3 && item.data.target === "cmd.exe") (item.type === 3 && item.data.target === "cmd.exe")
) { ) {

View File

@ -13,6 +13,7 @@ import cacheData from "../commons/cacheData";
import { import {
getMainBackgorunColor, getMainBackgorunColor,
getWindowInScreen, getWindowInScreen,
mainWindowExist,
sendToWebContent, sendToWebContent,
} from "../commons"; } from "../commons";
import { release } from "node:os"; import { release } from "node:os";
@ -24,8 +25,6 @@ let mainWindow: BrowserWindow | null = null;
* *
*/ */
function createMainWindow() { function createMainWindow() {
// 预热
global.addon.hasRunas(process.execPath);
// 如果窗口存在先关闭窗口 // 如果窗口存在先关闭窗口
if (mainWindow && !mainWindow.isDestroyed() && mainWindow.isVisible()) { if (mainWindow && !mainWindow.isDestroyed() && mainWindow.isVisible()) {
mainWindow.close(); mainWindow.close();
@ -182,6 +181,10 @@ function createMainWindow() {
sendToWebContent("mainWindow", "onCollapseSubClassification", {}); sendToWebContent("mainWindow", "onCollapseSubClassification", {});
} }
}); });
// 主窗口关闭事件
mainWindow.on("closed", () => {
app.quit();
});
// 创建鼠标hook // 创建鼠标hook
let mousedownClassName = null; let mousedownClassName = null;
addon.createMouseHook((...args: any[]) => { addon.createMouseHook((...args: any[]) => {
@ -215,6 +218,8 @@ function createMainWindow() {
// 中间单击 // 中间单击
showHideMouseWheelClick(); showHideMouseWheelClick();
} }
// 失去焦点隐藏
onBlurHide();
} }
}); });
// 禁用标题栏右键 // 禁用标题栏右键
@ -229,6 +234,50 @@ function createMainWindow() {
}); });
} }
/**
*
*/
function onBlurHide() {
if (
mainWindowExist() &&
global.mainWindow.isVisible() &&
global.setting.general.hideLoseFocus &&
!global.setting.general.alwaysTop &&
global.mainWindow.getChildWindows().length === 0 &&
!global.mainWindowShowDialog &&
!hasCursorPosWindow(global.mainWindow)
) {
// 隐藏窗口
hideMainWindow();
}
}
/**
*
*/
function hasCursorPosWindow(window: BrowserWindow) {
if (window && !window.isDestroyed() && window.isVisible()) {
// 获取鼠标位置
let point = screen.getCursorScreenPoint();
// 窗口位置信息
let bounds = window.getBounds();
// 判断鼠标是否在窗口以外
if (
point.x < bounds.x ||
point.x > bounds.x + bounds.width ||
point.y < bounds.y ||
point.y > bounds.y + bounds.height
) {
// 窗口以外
return false;
} else {
// 窗口以内
return true;
}
}
return false;
}
/** /**
* *
* @param blurHide * @param blurHide
@ -254,6 +303,9 @@ function showMainWindowBefore(
* @param autoHide * @param autoHide
*/ */
function showMainWindow(blurHide: boolean, autoHide = false) { function showMainWindow(blurHide: boolean, autoHide = false) {
if (!mainWindowExist()) {
return;
}
// flag // flag
let flag = true; let flag = true;
// 是否开启勿扰模式 // 是否开启勿扰模式
@ -268,12 +320,12 @@ function showMainWindow(blurHide: boolean, autoHide = false) {
} }
if (flag) { if (flag) {
if (!global.setting.general.alwaysTop) { if (!global.setting.general.alwaysTop) {
mainWindow.setAlwaysOnTop(true, "screen-saver"); global.mainWindow.setAlwaysOnTop(true, "screen-saver");
} }
global.mainWindow.show(); global.mainWindow.show();
global.mainWindow.focus(); global.mainWindow.focus();
if (!global.setting.general.alwaysTop) { if (!global.setting.general.alwaysTop) {
mainWindow.setAlwaysOnTop(false); global.mainWindow.setAlwaysOnTop(false);
} }
global.blurHide = blurHide; global.blurHide = blurHide;
} }
@ -283,7 +335,7 @@ function showMainWindow(blurHide: boolean, autoHide = false) {
* *
*/ */
function hideMainWindow() { function hideMainWindow() {
if (global.mainWindow.isVisible()) { if (mainWindowExist() && global.mainWindow.isVisible()) {
global.mainWindow.hide(); global.mainWindow.hide();
global.blurHide = false; global.blurHide = false;
} }
@ -344,10 +396,13 @@ function createTray(show: boolean) {
* @returns * @returns
*/ */
function edgeAdsorb(display: Display | null, workArea = false) { function edgeAdsorb(display: Display | null, workArea = false) {
if (!mainWindowExist()) {
return;
}
// 如果勾选停靠在桌面边缘时自动隐藏,放行 // 如果勾选停靠在桌面边缘时自动隐藏,放行
if ( if (
global.mainWindow.isDestroyed() || !global.setting.general.edgeAdsorb &&
(!global.setting.general.edgeAdsorb && !global.setting.general.edgeAutoHide) !global.setting.general.edgeAutoHide
) { ) {
return; return;
} }
@ -355,7 +410,7 @@ function edgeAdsorb(display: Display | null, workArea = false) {
// 清空方向 // 清空方向
global.mainWindowDirection = null; global.mainWindowDirection = null;
// 屏幕 // 屏幕
let displays = display ? [display] : getWindowInScreen(mainWindow); let displays = display ? [display] : getWindowInScreen(global.mainWindow);
if (displays.length > 1 || displays.length === 0) { if (displays.length > 1 || displays.length === 0) {
return; return;
} }
@ -444,6 +499,9 @@ function edgeAdsorb(display: Display | null, workArea = false) {
* *
*/ */
function showFollowMousePosition() { function showFollowMousePosition() {
if (!mainWindowExist()) {
return;
}
// 当永远居中、固定位置勾选后不能使用显示时跟随鼠标位置 // 当永远居中、固定位置勾选后不能使用显示时跟随鼠标位置
if ( if (
!global.setting.general.alwaysCenter && !global.setting.general.alwaysCenter &&
@ -474,6 +532,9 @@ function showFollowMousePosition() {
* / * /
*/ */
function showHideMouseWheelClick() { function showHideMouseWheelClick() {
if (!mainWindowExist()) {
return;
}
if (global.setting.general.showHideMouseWheelClick) { if (global.setting.general.showHideMouseWheelClick) {
if (global.mainWindow.isVisible()) { if (global.mainWindow.isVisible()) {
hideMainWindow(); hideMainWindow();
@ -487,8 +548,11 @@ function showHideMouseWheelClick() {
* *
*/ */
function alwaysCenter() { function alwaysCenter() {
if (!mainWindowExist()) {
return;
}
if (global.setting.general.alwaysCenter) { if (global.setting.general.alwaysCenter) {
mainWindow.center(); global.mainWindow.center();
} }
} }
@ -499,26 +563,32 @@ function alwaysCenter() {
* @returns * @returns
*/ */
function autoHide(size: number, timer: boolean) { function autoHide(size: number, timer: boolean) {
if (global.mainWindow.isDestroyed() || !global.setting.general.edgeAutoHide) { if (!mainWindowExist()) {
return;
}
if (!global.setting.general.edgeAutoHide) {
return; return;
} }
// 当有子窗口时不自动隐藏 // 当有子窗口时不自动隐藏
if (mainWindow.getChildWindows().length > 0 || global.mainWindowShowDialog) { if (
global.mainWindow.getChildWindows().length > 0 ||
global.mainWindowShowDialog
) {
return; return;
} }
let x = screen.getCursorScreenPoint().x; let x = screen.getCursorScreenPoint().x;
let y = screen.getCursorScreenPoint().y; let y = screen.getCursorScreenPoint().y;
try { try {
// 屏幕 // 屏幕
let displays = getWindowInScreen(mainWindow); let displays = getWindowInScreen(global.mainWindow);
if (displays.length > 1 || displays.length === 0) { if (displays.length > 1 || displays.length === 0) {
return; return;
} }
// 屏幕区域 // 屏幕区域
let displayBounds = displays[0].bounds; let displayBounds = displays[0].bounds;
// 窗口位置信息 // 窗口位置信息
let bounds = mainWindow.getBounds(); let bounds = global.mainWindow.getBounds();
if (mainWindow.isVisible()) { if (global.mainWindow.isVisible()) {
let flag = false; let flag = false;
if (bounds.x === displayBounds.x && bounds.y === displayBounds.y) { if (bounds.x === displayBounds.x && bounds.y === displayBounds.y) {
// 左上角 // 左上角
@ -693,12 +763,15 @@ function doubleClickTaskbar(
mousedownClassName: string | null, mousedownClassName: string | null,
className: string | null className: string | null
) { ) {
if (!mainWindowExist()) {
return;
}
// 必须开启设置 // 必须开启设置
if (!global.setting.general.showHideDoubleClickTaskbar) { if (!global.setting.general.showHideDoubleClickTaskbar) {
return; return;
} }
// 获取屏幕 // 获取屏幕
let displays = getWindowInScreen(mainWindow); let displays = getWindowInScreen(global.mainWindow);
if ( if (
displays.length > 1 || displays.length > 1 ||
displays.length === 0 || displays.length === 0 ||
@ -734,7 +807,7 @@ function doubleClickTaskbar(
// 清空计数 // 清空计数
global.doubleClickTaskbarCounter = 0; global.doubleClickTaskbarCounter = 0;
// 显示或隐藏 // 显示或隐藏
if (mainWindow.isVisible()) { if (global.mainWindow.isVisible()) {
hideMainWindow(); hideMainWindow();
} else { } else {
showMainWindowBefore(false); showMainWindowBefore(false);

View File

@ -5,7 +5,11 @@ import { hideMainWindow, showMainWindowBefore } from "../main/index";
import { list as selectClassificationList } from "../classification/data"; import { list as selectClassificationList } from "../classification/data";
import { list as selectItemList } from "../item/data"; import { list as selectItemList } from "../item/data";
import { run } from "../item"; import { run } from "../item";
import { closeWindow, getMainBackgorunColor } from "../commons/index"; import {
closeWindow,
getMainBackgorunColor,
mainWindowExist,
} from "../commons/index";
import { import {
createQuickSearchWindow, createQuickSearchWindow,
hideQuickSearchWindow, hideQuickSearchWindow,
@ -83,10 +87,12 @@ function setShortcutKey(setting: Setting = global.setting) {
globalShortcut.register( globalShortcut.register(
setting.general.showHideShortcutKey.replace("Win", "Super"), setting.general.showHideShortcutKey.replace("Win", "Super"),
() => { () => {
if (global.mainWindow.isVisible()) { if (mainWindowExist()) {
hideMainWindow(); if (global.mainWindow.isVisible()) {
} else { hideMainWindow();
showMainWindowBefore(true); } else {
showMainWindowBefore(true);
}
} }
} }
); );
@ -104,8 +110,10 @@ function setShortcutKey(setting: Setting = global.setting) {
globalShortcut.register( globalShortcut.register(
classification.shortcutKey.replace("Win", "Super"), classification.shortcutKey.replace("Win", "Super"),
() => { () => {
// 分类 if (mainWindowExist()) {
showMainWindowBefore(true, false, classification.id); // 分类
showMainWindowBefore(true, false, classification.id);
}
} }
); );
} catch (e) { } catch (e) {
@ -123,17 +131,19 @@ function setShortcutKey(setting: Setting = global.setting) {
globalShortcut.register( globalShortcut.register(
item.shortcutKey.replace("Win", "Super"), item.shortcutKey.replace("Win", "Super"),
() => { () => {
// flag if (mainWindowExist()) {
let flag = true; // flag
// 是否开启勿扰模式 let flag = true;
if (global.setting.general.notDisturb) { // 是否开启勿扰模式
if (global.addon.isFullscreen()) { if (global.setting.general.notDisturb) {
flag = false; if (global.addon.isFullscreen()) {
flag = false;
}
}
if (flag) {
// 项目
run("main", "open", item);
} }
}
if (flag) {
// 项目
run("main", "open", item);
} }
} }
); );

View File

@ -5,7 +5,7 @@ import {
newItem, newItem,
} from "../../commons/utils/common"; } from "../../commons/utils/common";
import { CommonItem, Item } from "../../types/item"; import { CommonItem, Item } from "../../types/item";
import { parse, join, extname } from "node:path"; import { parse, join } from "node:path";
import { readdirSync, readFileSync, statSync, writeFileSync } from "node:fs"; import { readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
import xml2js from "xml2js"; import xml2js from "xml2js";
import { newCommonItem, newCommonItemData } from "../../commons/utils/common"; import { newCommonItem, newCommonItemData } from "../../commons/utils/common";
@ -43,11 +43,6 @@ process.parentPort.once("message", async (event) => {
res = await getStartMenuItemList(dataParam); res = await getStartMenuItemList(dataParam);
} else if (params.name === "getAppxItemList") { } else if (params.name === "getAppxItemList") {
res = await getAppxItemList(); res = await getAppxItemList();
} else if (params.name === "getDropItemInfo") {
res = await getDropItemInfo(
dataParam.classificationId,
dataParam.pathList
);
} else if (params.name === "refreshItemIcon") { } else if (params.name === "refreshItemIcon") {
res = await refreshItemIcon(dataParam); res = await refreshItemIcon(dataParam);
} else if (params.name === "getDirectoryItemList") { } else if (params.name === "getDirectoryItemList") {
@ -558,90 +553,6 @@ function getPropertiesIcon(installLocation: string, result: any) {
return null; return null;
} }
/**
*
* @param classificationId
* @param pathList
*/
async function getDropItemInfo(
classificationId: number,
pathList: Array<string>
) {
// 项目列表
let itemList: Array<Item> = [];
// 解析文件信息并添加项目
for (const path of pathList) {
try {
// item
let item = newItem({ classificationId });
// 目标
item.data.target = path;
// 名称
item.name = getFileName(item.data.target);
// 判断是否是快捷方式,如果是的话,需要获取真实路径
if (mime.getType(path) === "application/x-ms-shortcut") {
// 快捷方式
// 获取真实文件路径和参数
let shortcutInfo: ShortcutInfo | null =
global.addon.getShortcutFileInfo(path);
if (shortcutInfo) {
// 路径
if (shortcutInfo.target) {
item.data.target = shortcutInfo.target;
}
// 参数
if (shortcutInfo.arguments) {
item.data.params = shortcutInfo.arguments;
}
}
}
// 获取图标
item.data.icon = await getFileIcon(item.data.target);
// 获取后缀判断是否是url
let ext = extname(item.data.target);
if (ext && ext.toLowerCase() === ".url") {
// url
let url = parseUrlFileContent(readFileSync(item.data.target, "utf-8"));
if (url && url.trim() !== "") {
item.data.target = url;
item.type = 2;
} else {
continue;
}
} else {
// 文件类型
let stats = statSync(item.data.target);
item.type = stats.isFile() ? 0 : 1;
}
// 去掉后缀
if (item.type === 0 || item.type === 2) {
item.name = deleteExtname(item.name);
}
// push
itemList.push(item);
} catch (e) {}
}
return itemList;
}
/**
* .url文件内容以获取URL
* @param content
* @returns
*/
function parseUrlFileContent(content: string) {
if (content) {
const lines = content.split("\n");
for (const line of lines) {
if (line.startsWith("URL=")) {
const url = line.substring(4).trim();
return url;
}
}
}
return null;
}
/** /**
* *
* @param itemList * @param itemList

View File

@ -1,7 +1,7 @@
{ {
"name": "dawn-launcher", "name": "dawn-launcher",
"productName": "Dawn Launcher", "productName": "Dawn Launcher",
"version": "1.4.7", "version": "1.5.1",
"main": "dist-electron/main/index.js", "main": "dist-electron/main/index.js",
"description": "Windows 快捷启动工具,帮助您整理杂乱无章的桌面,分门别类管理您的桌面快捷方式,让您的桌面保持干净整洁。", "description": "Windows 快捷启动工具,帮助您整理杂乱无章的桌面,分门别类管理您的桌面快捷方式,让您的桌面保持干净整洁。",
"author": "FanChenIO", "author": "FanChenIO",

View File

@ -201,12 +201,3 @@ fn shell_execute(operation: String, file: String, params: String, start_location
fn system_item_execute(target: String, params: Option<String>) { fn system_item_execute(target: String, params: Option<String>) {
windows::system_item_execute(&target, params.as_deref()) windows::system_item_execute(&target, params.as_deref())
} }
/**
*
*/
#[allow(dead_code)]
#[napi]
fn has_runas(path: String) -> bool {
windows::has_runas(&path)
}

View File

@ -42,15 +42,14 @@ use windows::{
Shell::{ Shell::{
BHID_SFUIObject, IContextMenu, IShellItem, IShellItemImageFactory, IShellLinkW, BHID_SFUIObject, IContextMenu, IShellItem, IShellItemImageFactory, IShellLinkW,
SHCreateItemFromParsingName, SHEmptyRecycleBinW, SHQueryUserNotificationState, SHCreateItemFromParsingName, SHEmptyRecycleBinW, SHQueryUserNotificationState,
ShellLink, CMF_NORMAL, CMINVOKECOMMANDINFO, GCS_VERBA, QUNS_ACCEPTS_NOTIFICATIONS, ShellLink, CMF_NORMAL, CMINVOKECOMMANDINFO, QUNS_ACCEPTS_NOTIFICATIONS, QUNS_APP,
QUNS_APP, QUNS_BUSY, QUNS_NOT_PRESENT, QUNS_PRESENTATION_MODE, QUNS_QUIET_TIME, QUNS_BUSY, QUNS_NOT_PRESENT, QUNS_PRESENTATION_MODE, QUNS_QUIET_TIME,
QUNS_RUNNING_D3D_FULL_SCREEN, SHERB_NOSOUND, SIIGBF_ICONONLY, SLGP_UNCPRIORITY, QUNS_RUNNING_D3D_FULL_SCREEN, SHERB_NOSOUND, SIIGBF_ICONONLY, SLGP_UNCPRIORITY,
}, },
WindowsAndMessaging::{ WindowsAndMessaging::{
CallNextHookEx, CreatePopupMenu, DestroyMenu, FindWindowW, GetClassNameW, CallNextHookEx, CreatePopupMenu, DestroyMenu, FindWindowW, GetClassNameW,
GetCursorPos, GetForegroundWindow, GetMenuItemCount, GetMenuItemInfoA, GetCursorPos, GetForegroundWindow, GetSystemMetrics, GetWindowRect, SendMessageW,
GetSystemMetrics, GetWindowRect, SendMessageW, SetForegroundWindow, SetForegroundWindow, SetWindowsHookExW, TrackPopupMenu, WindowFromPoint, HHOOK,
SetWindowsHookExW, TrackPopupMenu, WindowFromPoint, HHOOK, MENUITEMINFOA, MIIM_ID,
MSLLHOOKSTRUCT, SC_MONITORPOWER, SM_CXSCREEN, SM_CYSCREEN, SW_NORMAL, TPM_NONOTIFY, MSLLHOOKSTRUCT, SC_MONITORPOWER, SM_CXSCREEN, SM_CYSCREEN, SW_NORMAL, TPM_NONOTIFY,
TPM_RETURNCMD, WH_MOUSE_LL, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, TPM_RETURNCMD, WH_MOUSE_LL, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN,
WM_MBUTTONUP, WM_MOUSEHWHEEL, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_RBUTTONDOWN, WM_MBUTTONUP, WM_MOUSEHWHEEL, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_RBUTTONDOWN,
@ -722,6 +721,8 @@ pub fn shell_execute(
start_location: Option<String>, start_location: Option<String>,
) { ) {
thread::spawn(move || { thread::spawn(move || {
// 是否是打开文件夹
let is_dir = operation == "explore";
// dir // dir
let dir = start_location.unwrap_or_else(|| { let dir = start_location.unwrap_or_else(|| {
// 判断是否是文件夹 // 判断是否是文件夹
@ -734,6 +735,10 @@ pub fn shell_execute(
path.parent().unwrap().display().to_string() path.parent().unwrap().display().to_string()
} }
}); });
// 文件夹
let dir_param = format!("\"{}\"", file.to_string());
let dir_param = HSTRING::from(dir_param.as_str());
let dir_param = PCWSTR(dir_param.as_ptr());
// HSTRING // HSTRING
let operation = HSTRING::from(operation.as_str()); let operation = HSTRING::from(operation.as_str());
let file = HSTRING::from(file.as_str()); let file = HSTRING::from(file.as_str());
@ -745,8 +750,18 @@ pub fn shell_execute(
let params = PCWSTR(params.as_ptr()); let params = PCWSTR(params.as_ptr());
let dir = PCWSTR(dir.as_ptr()); let dir = PCWSTR(dir.as_ptr());
unsafe { unsafe {
// execute if is_dir {
ShellExecuteW(None, operation, file, params, dir, SW_SHOWDEFAULT); ShellExecuteW(
None,
w!("open"),
w!("explorer.exe"),
dir_param,
None,
SW_SHOWDEFAULT,
);
} else {
ShellExecuteW(None, operation, file, params, dir, SW_SHOWDEFAULT);
}
} }
}); });
} }
@ -789,68 +804,3 @@ pub fn system_item_execute(target: &str, params: Option<&str>) {
} }
} }
} }
/**
*
*/
pub fn has_runas(path: &str) -> bool {
// IShellItem
let path = HSTRING::from(path);
if let Ok(shell_item) =
unsafe { SHCreateItemFromParsingName::<_, _, IShellItem>(PCWSTR(path.as_ptr()), None) }
{
// IContextMenu
if let Ok(context_menu) =
unsafe { shell_item.BindToHandler::<_, IContextMenu>(None, &BHID_SFUIObject) }
{
// Menu
if let Ok(menu) = unsafe { CreatePopupMenu() } {
// 写入菜单
if let Ok(()) =
unsafe { context_menu.QueryContextMenu(menu, 0, 1, 0x7FFF, CMF_NORMAL) }
{
// 获取菜单总数
let count = unsafe { GetMenuItemCount(menu) };
// 循环每一项菜单
for i in 0..count {
// 获取菜单信息
let mut menu_info = MENUITEMINFOA::default();
menu_info.cbSize = std::mem::size_of::<MENUITEMINFOA>() as u32;
menu_info.fMask = MIIM_ID;
if unsafe { GetMenuItemInfoA(menu, i as u32, true, &mut menu_info) }
.as_bool()
{
// idcmd
let idcmd = menu_info.wID as usize - 1;
// 菜单项比如在指定范围内
if idcmd >= 1 && idcmd <= 0x7FFF {
// 获取菜单命令信息
let mut verb = [0u8; 256];
let pstr = PSTR(verb.as_mut_ptr());
if let Ok(()) = unsafe {
context_menu.GetCommandString(
menu_info.wID as usize - 1,
GCS_VERBA,
None,
pstr,
verb.len() as u32,
)
} {
if let Ok(command) = unsafe { pstr.to_string() } {
if command.to_lowercase() == "runas" {
return true;
}
}
}
}
}
}
unsafe {
DestroyMenu(menu);
}
}
}
}
}
false
}

View File

@ -34,7 +34,7 @@
/> />
<p class="mt-4">Dawn Launcher {{ version }}</p> <p class="mt-4">Dawn Launcher {{ version }}</p>
<p class="mt-2"> <p class="mt-2">
Copyright © 2022-2024 Dawn Launcher. All Rights Reserved Copyright © 2022-2025 Dawn Launcher. All Rights Reserved
</p> </p>
<p class="mt-2"> <p class="mt-2">
{{ store.language.officialWebsite }}{{ store.language.colon {{ store.language.officialWebsite }}{{ store.language.colon

View File

@ -523,6 +523,8 @@ onMounted(() => {
// //
listens.push( listens.push(
window.main.onShowWindowBefore((data) => { window.main.onShowWindowBefore((data) => {
//
store.search = false;
if (classificationContentRef.value) { if (classificationContentRef.value) {
// IDID // IDID
let selectedClassificationId: number | null = let selectedClassificationId: number | null =

View File

@ -329,9 +329,7 @@
v-if=" v-if="
selectedMenuId === 0 && selectedMenuId === 0 &&
form.data.target && form.data.target &&
form.data.target.trim() !== '' && form.data.target.trim() !== ''
(getFileExtname(form.data.target) === 'exe' ||
getFileExtname(form.data.target) === 'bat')
" "
v-model:checked="form.data.runAsAdmin" v-model:checked="form.data.runAsAdmin"
:focusable="false" :focusable="false"
@ -459,7 +457,6 @@ import {
isAbsolutePath, isAbsolutePath,
deleteExtname, deleteExtname,
getFileName, getFileName,
getFileExtname,
} from "../../../commons/utils/common"; } from "../../../commons/utils/common";
import SystemItemList from "./components/SystemItemList.vue"; import SystemItemList from "./components/SystemItemList.vue";
import StartMenuItemList from "./components/StartMenuItemList.vue"; import StartMenuItemList from "./components/StartMenuItemList.vue";
@ -656,12 +653,6 @@ async function confirm() {
if (!success) { if (!success) {
return; return;
} }
//
let ext = getFileExtname(form.data.target);
// exebatfalse
if (form.data.runAsAdmin && (!ext || (ext !== "exe" && ext !== "bat"))) {
form.data.runAsAdmin = false;
}
if (!id) { if (!id) {
// //
await addItem(); await addItem();

View File

@ -130,6 +130,7 @@ import {
setItemWidth, setItemWidth,
run, run,
removeInvalidItem, removeInvalidItem,
showItemList,
} from "../js"; } from "../js";
import ItemList from "./List.vue"; import ItemList from "./List.vue";
import { Item } from "../../../../types/item"; import { Item } from "../../../../types/item";
@ -315,12 +316,21 @@ function createItemSortable() {
let fromClassificationId = parseInt( let fromClassificationId = parseInt(
event.from.getAttribute("classification-id")! event.from.getAttribute("classification-id")!
); );
// let fromClassification =
const currentItem = getClassificationById(fromClassificationId);
getItemListByClassificationId(fromClassificationId)[ if (fromClassification) {
event.oldIndex let itemList =
]; getItemListByClassificationId(fromClassificationId);
fromIdList.push(currentItem.id); if (itemList) {
let copyItemList = JSON.parse(JSON.stringify(itemList));
//
const currentItem = showItemList(
copyItemList,
fromClassification
)[event.oldIndex];
fromIdList.push(currentItem.id);
}
}
} else { } else {
// //
for (const value of store.itemBatchOperationDataArray) { for (const value of store.itemBatchOperationDataArray) {

View File

@ -240,9 +240,9 @@ function runItem(e: any, dbclick: boolean) {
let item = getItemById(itemId); let item = getItemById(itemId);
if (item && item.data) { if (item && item.data) {
if (dbclick && store.setting.item.doubleClickOpen) { if (dbclick && store.setting.item.doubleClickOpen) {
run("main", item.data.runAsAdmin ? "runas" : "open", item); run("main", "open", item);
} else if (!dbclick && !store.setting.item.doubleClickOpen) { } else if (!dbclick && !store.setting.item.doubleClickOpen) {
run("main", item.data.runAsAdmin ? "runas" : "open", item); run("main", "open", item);
} }
} }
} }