From c71ed9a982a3553ae55eb85cbbd5e0f3a0814a1e Mon Sep 17 00:00:00 2001 From: cast1e Date: Thu, 17 Oct 2024 22:13:22 +0800 Subject: [PATCH] single instance & bug fixes --- wallitor-core/conFig.cpp | 22 ----- wallitor-core/conFig.h | 13 --- wallitor-core/dllmain.cpp | 12 --- wallitor-core/playerInstance.cpp | 82 +++---------------- wallitor-core/playerInstance.h | 12 --- wallitor-core/wallitor-core.vcxproj | 2 - wallitor-core/wallitor-core.vcxproj.filters | 6 -- wallitor-gui/src-tauri/Cargo.lock | 46 +++++++++++ wallitor-gui/src-tauri/Cargo.toml | 2 + wallitor-gui/src-tauri/src/handler/apply.rs | 38 ++++++--- wallitor-gui/src-tauri/src/handler/file.rs | 26 +++--- wallitor-gui/src-tauri/src/handler/mod.rs | 10 ++- .../src-tauri/src/handler/wallpaper.rs | 8 +- wallitor-gui/src-tauri/src/lib.rs | 10 ++- wallitor-gui/src-tauri/src/reader.rs | 42 ++++++---- 15 files changed, 145 insertions(+), 186 deletions(-) delete mode 100644 wallitor-core/conFig.cpp delete mode 100644 wallitor-core/conFig.h diff --git a/wallitor-core/conFig.cpp b/wallitor-core/conFig.cpp deleted file mode 100644 index e15e7a7..0000000 --- a/wallitor-core/conFig.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "pch.h" -#include "conFig.h" - -conFig::conFig(const char* ffpath,const char* videoPath, BOOL mute) { - std::string tmp =ffpath; - this->ffpath = std::wstring(tmp.begin(), tmp.end()); - tmp = videoPath; - this->videoPath = std::wstring(tmp.begin(), tmp.end()); - this->mute = mute; -} - -conFig::conFig(const conFig& config) { - this->ffpath = config.ffpath; - this->mute = config.mute; - this->videoPath = config.videoPath; -} - -conFig::conFig() { - this->ffpath = L""; - this->mute = TRUE; - this->videoPath = L""; -} diff --git a/wallitor-core/conFig.h b/wallitor-core/conFig.h deleted file mode 100644 index f4c77fb..0000000 --- a/wallitor-core/conFig.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include -class conFig -{ -public: - std::wstring ffpath; - std::wstring videoPath; - BOOL mute; - conFig(const char* ffpath, const char* videoPath,BOOL mute); - conFig(const conFig& config); - conFig(); -}; - diff --git a/wallitor-core/dllmain.cpp b/wallitor-core/dllmain.cpp index 2dc9cb3..c017365 100644 --- a/wallitor-core/dllmain.cpp +++ b/wallitor-core/dllmain.cpp @@ -18,18 +18,6 @@ BOOL APIENTRY DllMain( HMODULE hModule, return TRUE; } -playerInstance* player_instance = NULL; - - extern "C" __declspec(dllexport) void init(const char* ffpath,const char* videoPath, BOOL mute) { - player_instance = new playerInstance(conFig(ffpath, videoPath, mute)); - player_instance->generate(); -} - - extern "C" __declspec(dllexport) void destroy() { - player_instance->exit(); - delete player_instance; - } - extern "C" __declspec(dllexport) BOOL set_wallpaper(const char* window_title) { return set_as_wallpaper(window_title); } diff --git a/wallitor-core/playerInstance.cpp b/wallitor-core/playerInstance.cpp index cb5cf5c..7990723 100644 --- a/wallitor-core/playerInstance.cpp +++ b/wallitor-core/playerInstance.cpp @@ -1,11 +1,6 @@ #include "pch.h" #include "playerInstance.h" -playerInstance::playerInstance(const conFig& config) { - this->config = config; - this->hFfplay = NULL; -} - HWND hWorkerw = NULL; static BOOL CALLBACK EnumWindowsProc(_In_ HWND hwnd, _In_ LPARAM Lparam) { @@ -17,67 +12,6 @@ static BOOL CALLBACK EnumWindowsProc(_In_ HWND hwnd, _In_ LPARAM Lparam) { return TRUE; } -BOOL playerInstance::showWindow(LPCWSTR lpParameter) { - if (this->hFfplay != NULL) { - DWORD dwPID = 0; - GetWindowThreadProcessId(hFfplay, &dwPID); - char strCmd[MAX_PATH] = { 0 }; - sprintf_s(strCmd, "taskkill /pid %d -f", dwPID); - system(strCmd); - } - STARTUPINFO si{ 0 }; - si.dwFlags = STARTF_USESHOWWINDOW; - si.wShowWindow = SW_HIDE; - PROCESS_INFORMATION pi{ 0 }; - if (CreateProcess(this->config.ffpath.c_str(), (LPWSTR)lpParameter, 0, 0, 0, CREATE_NO_WINDOW, 0, 0, &si, &pi)) { - Sleep(600);//等待视频播放器启动完成 - HWND hProgman = FindWindow(L"Progman", 0);// 找到PI窗口 - SendMessageTimeout(hProgman, 0x052c, 0, 0, 0, 100, 0);// 给它发特殊消息 - this->hFfplay = FindWindowW(L"SDL_app", 0);// 找到视频窗口 - SetParent(hFfplay, hProgman);// 将视频窗口设苦为PM的子窗口 - int systemWidth = GetSystemMetrics(0); - int systemHeight = GetSystemMetrics(1); - RECT cRct; - GetWindowRect(hFfplay, &cRct); - //if (horw) { - int width = cRct.right - cRct.left; - int x = (systemWidth - width) / 2; - MoveWindow(hFfplay, 0, 0, systemWidth, systemHeight, 1); - /* } - else { - int height = cRct.bottom - cRct.top; - int x = (sheight - height) / 2; - MoveWindow(hFfplay, 0, x, cRct.right - cRct.left, cRct.bottom - cRct.top, 0); - }*/ - EnumWindows(EnumWindowsProc, 0);// 找到第二个workerw窗口并隐藏它 - return TRUE; - } - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - return FALSE; -} - -void playerInstance::generate() { - std::wstring fcmd = L" \""; - fcmd += this->config.videoPath + L"\""; - fcmd += L" -noborder -loop 0"; - if (this->config.mute) { - fcmd += L" -an"; - } - fcmd += L" -fs"; - this->showWindow(fcmd.c_str()); -} - -void playerInstance::exit() { - if (this->hFfplay != NULL) { - DWORD dwPID = 0; - GetWindowThreadProcessId(this->hFfplay, &dwPID); - char strCmd[MAX_PATH] = { 0 }; - sprintf_s(strCmd, "taskkill /pid %d -f", dwPID); - system(strCmd); - } -} - BOOL try_find_worker(HWND hProgman,HWND hPlayer) { HWND hWorkerW = FindWindowEx(hProgman, 0, L"WorkerW", 0); if (hWorkerW != NULL) { @@ -87,10 +21,9 @@ BOOL try_find_worker(HWND hProgman,HWND hPlayer) { else return FALSE; } -BOOL shell_in_progman(HWND hProgman) { +HWND shell_in_progman(HWND hProgman) { HWND hShell = FindWindowEx(hProgman, 0, L"SHELLDLL_DefView", 0); - if (hShell) return TRUE; - else return FALSE; + return hShell; } BOOL set_as_wallpaper(const char* window_title) { @@ -99,8 +32,15 @@ BOOL set_as_wallpaper(const char* window_title) { std::string tmp = window_title; HWND hPlayer = FindWindowW(0, std::wstring(tmp.begin(), tmp.end()).c_str());// 找到视频窗口 if (hPlayer == NULL) return FALSE; - if (shell_in_progman(hProgman)) { - return try_find_worker(hProgman, hPlayer); + HWND hDefView = shell_in_progman(hProgman); + if (hDefView!=NULL) { + if (try_find_worker(hProgman, hPlayer)) { + ShowWindow(hDefView, SW_HIDE); + Sleep(0); + ShowWindow(hDefView, SW_SHOWNORMAL); + return TRUE; + } + else return FALSE; } else { SetParent(hPlayer, hProgman);// 将视频窗口设苦为PM的子窗口 diff --git a/wallitor-core/playerInstance.h b/wallitor-core/playerInstance.h index 077bdf4..5ccbb8c 100644 --- a/wallitor-core/playerInstance.h +++ b/wallitor-core/playerInstance.h @@ -1,17 +1,5 @@ #pragma once #include -#include "conFig.h" -class playerInstance -{ -private: - HWND hFfplay; - conFig config; -public: - playerInstance(const conFig& config); - BOOL showWindow(LPCWSTR lpParameter); - void generate(); - void exit(); -}; BOOL set_as_wallpaper(const char* window_title); BOOL detectWindowMaximized(); \ No newline at end of file diff --git a/wallitor-core/wallitor-core.vcxproj b/wallitor-core/wallitor-core.vcxproj index ab31324..3299ca0 100644 --- a/wallitor-core/wallitor-core.vcxproj +++ b/wallitor-core/wallitor-core.vcxproj @@ -142,13 +142,11 @@ - - Create diff --git a/wallitor-core/wallitor-core.vcxproj.filters b/wallitor-core/wallitor-core.vcxproj.filters index bff130d..83c0490 100644 --- a/wallitor-core/wallitor-core.vcxproj.filters +++ b/wallitor-core/wallitor-core.vcxproj.filters @@ -24,9 +24,6 @@ 澶存枃浠 - - 澶存枃浠 - @@ -38,8 +35,5 @@ 婧愭枃浠 - - 婧愭枃浠 - \ No newline at end of file diff --git a/wallitor-gui/src-tauri/Cargo.lock b/wallitor-gui/src-tauri/Cargo.lock index b1d19e2..3efa226 100644 --- a/wallitor-gui/src-tauri/Cargo.lock +++ b/wallitor-gui/src-tauri/Cargo.lock @@ -103,6 +103,30 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "async-executor" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-fs" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" +dependencies = [ + "async-lock", + "blocking", + "futures-lite", +] + [[package]] name = "async-io" version = "2.3.4" @@ -3685,6 +3709,21 @@ dependencies = [ "tokio", ] +[[package]] +name = "tauri-plugin-single-instance" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a25ac834491d089699a2bc9266a662faf373c9f779f05a2235bc6e4d9e61769a" +dependencies = [ + "log", + "serde", + "serde_json", + "tauri", + "thiserror", + "windows-sys 0.59.0", + "zbus", +] + [[package]] name = "tauri-runtime" version = "2.1.0" @@ -4213,6 +4252,7 @@ dependencies = [ "tauri-plugin-dialog", "tauri-plugin-fs", "tauri-plugin-shell", + "tauri-plugin-single-instance", "window-vibrancy", ] @@ -4866,9 +4906,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b8e3d6ae3342792a6cc2340e4394334c7402f3d793b390d2c5494a4032b3030" dependencies = [ "async-broadcast", + "async-executor", + "async-fs", + "async-io", + "async-lock", "async-process", "async-recursion", + "async-task", "async-trait", + "blocking", "derivative", "enumflags2", "event-listener", diff --git a/wallitor-gui/src-tauri/Cargo.toml b/wallitor-gui/src-tauri/Cargo.toml index f33cba4..60424ee 100644 --- a/wallitor-gui/src-tauri/Cargo.toml +++ b/wallitor-gui/src-tauri/Cargo.toml @@ -29,4 +29,6 @@ lazy_static = "1.5.0" [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] tauri-plugin-autostart = "2.0.0-rc" +tauri-plugin-single-instance = "2.0.0-rc" + diff --git a/wallitor-gui/src-tauri/src/handler/apply.rs b/wallitor-gui/src-tauri/src/handler/apply.rs index b64afba..bd7ae2d 100644 --- a/wallitor-gui/src-tauri/src/handler/apply.rs +++ b/wallitor-gui/src-tauri/src/handler/apply.rs @@ -1,20 +1,32 @@ -use libloading::{self,Library}; -use std::{ffi::CString, ops::Deref, sync::Arc}; +use crate::handler::get_absolute_path; use lazy_static::lazy_static; +use libloading::{self, Library}; +use std::{ffi::CString, ops::Deref, sync::Arc}; -struct CoreModule{ - _module:Arc, - pub set_wallpaper:libloading::os::windows::Symbol i8>, - pub any_maximized:libloading::os::windows::Symbol i8> +struct CoreModule { + _module: Arc, + pub set_wallpaper: libloading::os::windows::Symbol i8>, + pub any_maximized: libloading::os::windows::Symbol i8>, } impl CoreModule { fn new(library_path: &str) -> CoreModule { + let library_dir = get_absolute_path(&String::from(library_path)); // 棣栧厛鍔犺浇鍔ㄦ佸簱 - let _module = Arc::new(unsafe { Library::new(library_path).unwrap()}); + let _module = Arc::new(unsafe { Library::new(library_dir).unwrap() }); // 鐒跺悗鑾峰彇绗﹀彿 - let set_wallpaper: libloading::os::windows::Symbol i8> = unsafe { _module.get:: i8>(b"set_wallpaper\0").unwrap().into_raw() }; - let any_maximized: libloading::os::windows::Symbol i8> = unsafe { _module.get:: i8>(b"any_maximized\0").unwrap().into_raw() }; + let set_wallpaper: libloading::os::windows::Symbol i8> = unsafe { + _module + .get:: i8>(b"set_wallpaper\0") + .unwrap() + .into_raw() + }; + let any_maximized: libloading::os::windows::Symbol i8> = unsafe { + _module + .get:: i8>(b"any_maximized\0") + .unwrap() + .into_raw() + }; // 杩斿洖鍒濆鍖栫殑缁撴瀯浣 CoreModule { _module, @@ -24,8 +36,8 @@ impl CoreModule { } } -lazy_static!{ - static ref core_module:CoreModule = CoreModule::new("wallitor-core.dll"); +lazy_static! { + static ref core_module: CoreModule = CoreModule::new("wallitor-core.dll"); } #[tauri::command] @@ -41,10 +53,10 @@ pub async fn set_wallpaper(title: String) -> bool { } #[tauri::command] -pub async fn any_zoomed()->bool{ +pub async fn any_zoomed() -> bool { unsafe { let res = core_module.any_maximized.deref()(); - if res == 0{ + if res == 0 { return false; } } diff --git a/wallitor-gui/src-tauri/src/handler/file.rs b/wallitor-gui/src-tauri/src/handler/file.rs index 6b95d2f..c033684 100644 --- a/wallitor-gui/src-tauri/src/handler/file.rs +++ b/wallitor-gui/src-tauri/src/handler/file.rs @@ -1,3 +1,4 @@ +use crate::handler::get_absolute_path; use crate::{reader, VERSION}; use serde::{Deserialize, Serialize}; use serde_json::json; @@ -7,9 +8,9 @@ use tauri::ipc::Response; #[tauri::command] pub async fn get_file(path: String) -> Response { - let p = Path::new(&path); - if let Ok(true) = fs::exists(p) { - let data: Vec = fs::read(p).unwrap(); + let p = get_absolute_path(&path); + if let Ok(true) = fs::exists(&p) { + let data: Vec = fs::read(&p).unwrap(); return tauri::ipc::Response::new(data); } tauri::ipc::Response::new(String::from("")) @@ -18,12 +19,12 @@ pub async fn get_file(path: String) -> Response { #[tauri::command] pub async fn read_resource_dir() -> String { let mut file_map = reader::FileMap::new(); - let path = Path::new(".\\resource"); - if let Ok(false) = fs::exists(path) { - fs::create_dir(path).expect("Can't create dir"); + let path = get_absolute_path(&String::from(".\\resource")); + if let Ok(false) = fs::exists(&path) { + fs::create_dir(&path).expect("Can't create dir"); } file_map - .read_resourse_directory(path) + .read_resourse_directory(&path) .expect("Can't read dir"); serde_json::to_string(&file_map).unwrap() } @@ -32,9 +33,10 @@ pub async fn read_resource_dir() -> String { pub async fn del_folder(path: String) -> bool { let p = Path::new(&path); if p.starts_with(".\\") { - if p.is_dir() { - if let Ok(true) = fs::exists(p) { - if fs::remove_dir_all(p).is_ok() { + let folder_path = get_absolute_path(&path); + if folder_path.is_dir() { + if let Ok(true) = fs::exists(&folder_path) { + if fs::remove_dir_all(&folder_path).is_ok() { return true; } } @@ -66,7 +68,7 @@ static SETTING_PATH: &str = "./settings.json"; #[tauri::command] pub async fn get_settings() -> String { - let setting_path = Path::new(SETTING_PATH); + let setting_path = get_absolute_path(&String::from(SETTING_PATH)); if let Ok(file) = fs::read(setting_path) { let mut settings: Settings = serde_json::from_slice(&file).unwrap(); settings.version = String::from(VERSION); @@ -79,7 +81,7 @@ pub async fn get_settings() -> String { #[tauri::command] pub async fn set_settings(settings: Settings) -> bool { - let setting_path = Path::new(SETTING_PATH); + let setting_path = get_absolute_path(&String::from(SETTING_PATH)); if fs::write(setting_path, json!(settings).to_string()).is_ok() { return true; } diff --git a/wallitor-gui/src-tauri/src/handler/mod.rs b/wallitor-gui/src-tauri/src/handler/mod.rs index 4346ffb..8d0593f 100644 --- a/wallitor-gui/src-tauri/src/handler/mod.rs +++ b/wallitor-gui/src-tauri/src/handler/mod.rs @@ -1,3 +1,11 @@ +pub mod apply; pub mod file; pub mod wallpaper; -pub mod apply; \ No newline at end of file + +use std::path::{Path, PathBuf}; + +pub fn get_absolute_path(path: &String) -> PathBuf { + let binding = std::env::current_exe().unwrap(); + let base_dir = binding.parent().unwrap(); + return base_dir.join(Path::new(path)); +} diff --git a/wallitor-gui/src-tauri/src/handler/wallpaper.rs b/wallitor-gui/src-tauri/src/handler/wallpaper.rs index fef5b9e..14bb807 100644 --- a/wallitor-gui/src-tauri/src/handler/wallpaper.rs +++ b/wallitor-gui/src-tauri/src/handler/wallpaper.rs @@ -1,3 +1,4 @@ +use crate::handler::get_absolute_path; use chrono::Local; use serde::{Deserialize, Serialize}; use serde_json::{self, json}; @@ -34,7 +35,8 @@ pub struct Config { #[tauri::command] pub async fn new_wallpaper(info: AddInfo) -> String { - let base_url = String::from("./resource"); + let base_path = get_absolute_path(&String::from("./resource")); + let base_url = base_path.to_str().unwrap(); let current_time: i64 = Local::now().timestamp(); let folder = format!("{}/{}", base_url, current_time); if fs::create_dir_all(Path::new(&folder)).is_err() { @@ -143,10 +145,10 @@ fn copy_preview(source_file: &String, target_dir: &String) -> bool { #[tauri::command] pub async fn edit_wallpaper(info: EditInfo) -> bool { - let folder_path = Path::new(&info.path); + let folder_path = &get_absolute_path(&info.path); if let Ok(true) = fs::exists(folder_path) { let config_path_str = format!("{}/config.json", info.path); - let config_path = Path::new(&config_path_str); + let config_path = &get_absolute_path(&config_path_str); if let Ok(file) = fs::read(config_path) { let mut config: Config = serde_json::from_slice(&file).unwrap(); config.info.description = info.description; diff --git a/wallitor-gui/src-tauri/src/lib.rs b/wallitor-gui/src-tauri/src/lib.rs index 4dd9399..4b8ee81 100644 --- a/wallitor-gui/src-tauri/src/lib.rs +++ b/wallitor-gui/src-tauri/src/lib.rs @@ -2,6 +2,7 @@ mod handler; mod reader; mod setup; extern crate lazy_static; +use tauri::Manager; use tauri_plugin_autostart::MacosLauncher; static VERSION: &str = "1.0.0"; @@ -10,11 +11,18 @@ static VERSION: &str = "1.0.0"; pub fn run() { tauri::Builder::default() .setup(setup::init) + .plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| { + let window = app.get_webview_window("main").expect("no main window"); + if let Ok(true) = window.is_minimized() { + let _ = window.unminimize(); + } + let _ = window.set_focus(); + })) .plugin(tauri_plugin_fs::init()) .plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_autostart::init( MacosLauncher::LaunchAgent, - Some(vec!["--flag1", "--flag2"]), + None, )) .invoke_handler(tauri::generate_handler![ handler::file::get_file, diff --git a/wallitor-gui/src-tauri/src/reader.rs b/wallitor-gui/src-tauri/src/reader.rs index b9db095..5cd76de 100644 --- a/wallitor-gui/src-tauri/src/reader.rs +++ b/wallitor-gui/src-tauri/src/reader.rs @@ -1,11 +1,11 @@ +use serde::{Serialize, Serializer}; +use std::collections::HashMap; use std::fs; use std::path::Path; -use serde::{ Serialize,Serializer}; -use std::collections::HashMap; enum FileType { File(String), - Directory(HashMap) + Directory(HashMap), } impl Serialize for FileType { @@ -14,43 +14,49 @@ impl Serialize for FileType { S: Serializer, { match self { - FileType::File(file) => serializer.serialize_str(file), // 鏂囦欢鍙簭鍒楀寲璺緞 - FileType::Directory(dir) => dir.serialize(serializer), // 鐩綍搴忓垪鍖栦负HashMap + FileType::File(file) => serializer.serialize_str(file), // 鏂囦欢鍙簭鍒楀寲璺緞 + FileType::Directory(dir) => dir.serialize(serializer), // 鐩綍搴忓垪鍖栦负HashMap } } } #[derive(Serialize)] pub struct FileMap { - files: HashMap, // 鐢ㄤ簬瀛樺偍鏂囦欢鍚嶅拰璺緞 + files: HashMap, // 鐢ㄤ簬瀛樺偍鏂囦欢鍚嶅拰璺緞 } impl FileMap { - pub fn new()->FileMap{ - FileMap{ - files:HashMap::new() + pub fn new() -> FileMap { + FileMap { + files: HashMap::new(), } } - fn read_resource(&self,p:&Path)->std::io::Result>{ - let mut files:HashMap = HashMap::new(); - for entry in fs::read_dir(p)?{ + fn read_resource(&self, p: &Path) -> std::io::Result> { + let mut files: HashMap = HashMap::new(); + for entry in fs::read_dir(p)? { let dir = entry?; let path = dir.path(); if path.is_file() { - files.insert(path.file_name().unwrap().to_string_lossy().to_string(), FileType::File(path.to_string_lossy().to_string())); + files.insert( + path.file_name().unwrap().to_string_lossy().to_string(), + FileType::File(path.to_string_lossy().to_string()), + ); } } Ok(files) } - - pub fn read_resourse_directory(&mut self,p:&Path)->std::io::Result<()>{ - for entry in fs::read_dir(p)?{ + + pub fn read_resourse_directory(&mut self, p: &Path) -> std::io::Result<()> { + for entry in fs::read_dir(p)? { let dir = entry?; let path = dir.path(); if path.is_dir() { - let resource = self.read_resource(path.as_path())?; - self.files.insert(path.to_string_lossy().to_string(), FileType::Directory(resource)) ; + let resource = self.read_resource(path.as_path())?; + self.files.insert( + path.to_string_lossy().to_string(), + FileType::Directory(resource), + ); } } Ok(())