Skip to content

Commit 2af4b69

Browse files
committed
支持命令行参数启动编组
1 parent b731c38 commit 2af4b69

File tree

10 files changed

+319
-138
lines changed

10 files changed

+319
-138
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "one-click-launch",
33
"private": true,
4-
"version": "1.0.3",
4+
"version": "1.0.4",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",

src-tauri/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "one-click-launch"
3-
version = "1.0.3"
3+
version = "1.0.4"
44
description = "One Click Launch"
55
authors = ["Silwings"]
66
edition = "2024"
@@ -31,8 +31,8 @@ serde = { version = "1", features = ["derive"] }
3131
serde_json = "1"
3232
thiserror = "2.0.3"
3333
anyhow = "1.0.93"
34-
tracing = "0.1" # 日志处理
35-
tracing-subscriber = "0.3" # 日志处理
34+
tracing = "0.1"
35+
tracing-subscriber = "0.3"
3636
windows = "0.58.0"
3737
sqlx = { version = "0.5", features = ["runtime-tokio-rustls", "sqlite"] }
3838
tokio = { version = "1.43.0", features = ["full"] }

src-tauri/src/api/launcher_api.rs

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,25 @@ pub async fn launch(app: AppHandle, launcher_id: i64) -> Result<(), OneClickLaun
301301
OneClickLaunchError::ExecutionError("Unable to get DatabaseManager".to_string()),
302302
)?;
303303

304-
let resources = launcher_resource::query_by_launcher_id(&db.pool, launcher_id).await?;
304+
let mut resources = launcher_resource::query_by_launcher_id(&db.pool, launcher_id).await?;
305+
306+
// 必须从启动资源中排除自己,防止出现死循环
307+
let app_path = current_exe_path_str()?;
308+
resources.retain(|e| {
309+
// 检查路径是否包含空格
310+
if e.path.contains(' ') {
311+
// 按空格拆分并取第一个部分进行比较
312+
e.path.split_whitespace().next() == Some(&app_path)
313+
} else {
314+
// 不包含空格时直接比较
315+
e.path.eq(&app_path)
316+
}
317+
});
318+
319+
if resources.is_empty() {
320+
tracing::debug!("资源列表为空");
321+
return Ok(());
322+
}
305323

306324
launch_resources(&app, &resources);
307325

@@ -354,17 +372,10 @@ pub async fn create_handler_shortcut(
354372
launcher_id: i64,
355373
db: State<'_, DatabaseManager>,
356374
) -> Result<String, OneClickLaunchError> {
357-
// 获取当前应用程序的绝对路径
358-
let exe_path = std::env::current_exe()?;
359-
360-
// 转换为 Windows 可识别的普通路径
361-
let mut app_path = exe_path.to_string_lossy().to_string();
362-
if app_path.starts_with(r"\\?\") {
363-
app_path = app_path.trim_start_matches(r"\\?\").to_string();
364-
}
365-
366375
let launcher = launcher::find_by_id(&db.pool, launcher_id).await?;
367376

377+
let app_path = current_exe_path_str()?;
378+
368379
// 构建参数
369380
let args = Some(vec![format!("launch {}", launcher_id)]);
370381

@@ -377,3 +388,15 @@ pub async fn create_handler_shortcut(
377388
)
378389
.map(|path| path.to_string_lossy().to_string())
379390
}
391+
392+
fn current_exe_path_str() -> Result<String, OneClickLaunchError> {
393+
// 获取当前应用程序的绝对路径
394+
let exe_path = std::env::current_exe()?;
395+
396+
// 转换为 Windows 可识别的普通路径
397+
let mut app_path = exe_path.to_string_lossy().to_string();
398+
if app_path.starts_with(r"\\?\") {
399+
app_path = app_path.trim_start_matches(r"\\?\").to_string();
400+
}
401+
Ok(app_path)
402+
}

src-tauri/src/constants.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use lazy_static::lazy_static;
22

33
lazy_static! {
44
pub static ref AUTO_START_FLAG: String = "--auto".to_string();
5+
pub static ref LAUNCH_SPECIFIED_LAUNCHER_KEY: String = "launch".to_string();
56
}
67

78
pub static APPLICATION_NAME: &str = "一键启动";

src-tauri/src/events/system_listeners.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ use crate::{
99
window_api,
1010
},
1111
constants::{
12-
self, AUTO_START_FLAG, AUTO_START_LAUNCHER_IDS_KEY, HIDE_AFTER_AUTO_START_KEY, THEME_KEY,
12+
self, AUTO_START_FLAG, AUTO_START_LAUNCHER_IDS_KEY, HIDE_AFTER_AUTO_START_KEY,
13+
LAUNCH_SPECIFIED_LAUNCHER_KEY, THEME_KEY,
1314
},
1415
db::{launcher_resource, settings},
1516
events::EventDispatcher,
17+
extract_arg_value,
1618
};
1719

1820
use super::{
@@ -59,6 +61,7 @@ fn register_application_startup_complete_listeners(app: &AppHandle) {
5961
hide_after_auto_start(&app_cloned, &payload);
6062
refresh_tray(&app_cloned);
6163
launch_auto_start_launchers(&app_cloned, &payload);
64+
launch_specified_launcher(&app_cloned, &payload);
6265
debug!("application_startup_complete_listeners 处理完成");
6366
});
6467
}
@@ -184,6 +187,20 @@ fn launch_auto_start_launchers(app: &AppHandle, payload: &ApplicationStartupComp
184187
}
185188
}
186189

190+
fn launch_specified_launcher(app: &AppHandle, payload: &ApplicationStartupCompletePayload) {
191+
// 如果启动命令指定了LAUNCH_SPECIFIED_LAUNCHER_KEY, 需要启动指定的编组
192+
if let Some(Ok(launcher_id)) = extract_arg_value(&payload.args, &LAUNCH_SPECIFIED_LAUNCHER_KEY)
193+
.map(|value| value.parse::<i64>())
194+
{
195+
let app_cloned = app.clone();
196+
tokio::spawn(async move {
197+
if let Err(e) = launcher_api::launch(app_cloned, launcher_id).await {
198+
tracing::error!("launcher launch fail: {}", e);
199+
}
200+
});
201+
}
202+
}
203+
187204
fn launch_then_exit(app: &AppHandle) {
188205
let app_cloned = app.clone();
189206
tauri::async_runtime::spawn(async move {

src-tauri/src/lib.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ use tauri::tray::TrayIcon;
1515
use tauri::{AppHandle, Manager};
1616
use tauri_plugin_autostart::MacosLauncher;
1717
use tracing::{debug, info};
18+
19+
use crate::constants::LAUNCH_SPECIFIED_LAUNCHER_KEY;
1820
mod api;
1921
mod constants;
2022
mod db;
@@ -125,12 +127,12 @@ pub async fn run() -> Result<()> {
125127
.manage(ScaleFactorChangedState {
126128
last_reset: Mutex::new(None),
127129
})
128-
// 优先注册单例插件
130+
// 必须优先注册单例插件
129131
.plugin(tauri_plugin_single_instance::init(|app, argv, cwd| {
130132
info!("run app: {}, {argv:?}, {cwd}", app.package_info().name);
131133

132-
if let Some(Ok(launcher_id)) =
133-
extract_arg_value(&argv, "launch").map(|value| value.parse::<i64>())
134+
if let Some(Ok(launcher_id)) = extract_arg_value(&argv, &LAUNCH_SPECIFIED_LAUNCHER_KEY)
135+
.map(|value| value.parse::<i64>())
134136
{
135137
let app_cloned = app.clone();
136138
tokio::spawn(async move {
@@ -189,7 +191,7 @@ fn register_listeners(app: &AppHandle) {
189191
register_system_listeners(app);
190192
}
191193

192-
fn extract_arg_value(argv: &[String], key: &str) -> Option<String> {
194+
pub fn extract_arg_value(argv: &[String], key: &str) -> Option<String> {
193195
let mut iter = argv.iter();
194196
while let Some(arg) = iter.next() {
195197
if arg == key {

src-tauri/tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"productName": "一键启动",
4-
"version": "1.0.3",
4+
"version": "1.0.4",
55
"identifier": "one-click-launch",
66
"build": {
77
"beforeDevCommand": "yarn dev",

src/launcher.vue

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474

7575
</div>
7676
</div>
77-
<button class="launch-button" :disabled="isLaunching" @click="launch">
77+
<button class="launch-button" :disabled="isLaunching || !data.resources?.length" @click="launch">
7878
<span v-if="!isLaunching">启动</span>
7979
<span v-else>
8080
<svg class="loading-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
@@ -248,7 +248,7 @@ export default {
248248
const moveLauncher = (type) => {
249249
emit("launcher-moved", props.launcherData.id, type);
250250
};
251-
251+
252252
const handleRightClick = (type) => {
253253
emit('show-context-menu', props.launcherData, type);
254254
};
@@ -562,4 +562,27 @@ hr {
562562
/* 点击时缩小效果 */
563563
transform: scale(0.95);
564564
}
565+
566+
.launch-button:disabled {
567+
background-color: #c6c8ca;
568+
color: #6c757d;
569+
cursor: not-allowed;
570+
/* 取消 hover/active 的缩放效果 */
571+
transform: none !important;
572+
/* 确保禁用状态可被识别 */
573+
pointer-events: auto;
574+
}
575+
576+
.launch-button:disabled:hover {
577+
background-color: #c6c8ca;
578+
/* 取消 hover 放大 */
579+
transform: none;
580+
}
581+
582+
.launch-button:disabled:active {
583+
background-color: #c6c8ca;
584+
/* 取消 active 缩小 */
585+
transform: none;
586+
}
587+
565588
</style>

0 commit comments

Comments
 (0)