Claude: Add shortcut on desktop
This commit is contained in:
parent
466667f800
commit
f7cdbe494c
@ -3,7 +3,6 @@ use std::path::PathBuf;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use crate::installer::validator::*;
|
use crate::installer::validator::*;
|
||||||
use crate::installer::downloader::DownloadManager;
|
use crate::installer::downloader::DownloadManager;
|
||||||
use crate::installer::SevenZDearchiver;
|
|
||||||
use crate::ui::download_progress::download_progress;
|
use crate::ui::download_progress::download_progress;
|
||||||
use crate::ui::game_selection::game_selection;
|
use crate::ui::game_selection::game_selection;
|
||||||
use crate::ui::installation_progress::installation_progress;
|
use crate::ui::installation_progress::installation_progress;
|
||||||
@ -24,7 +23,6 @@ pub enum InstallerState {
|
|||||||
Complete,
|
Complete,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct DownloadState {
|
pub struct DownloadState {
|
||||||
pub progress: f32,
|
pub progress: f32,
|
||||||
@ -281,16 +279,7 @@ impl SinfarInstallerApp<> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_installation(&mut self) {
|
pub fn start_installation(&mut self) {
|
||||||
// Use tokio runtime to handle the async installation
|
// Reset state
|
||||||
let install_path = self.install_path.clone().expect("Install path should be set");
|
|
||||||
let ee_exe_path = self.ee_exe_path.clone();
|
|
||||||
let download_state = self.download_state.clone();
|
|
||||||
let progress_state = self.download_state.clone();
|
|
||||||
let eframe_ctx = self.eframe_ctx.clone().expect("eframe context should be set");
|
|
||||||
let runtime = self.runtime.clone();
|
|
||||||
let game_type = self.game_type.clone().expect("Game type should be set");
|
|
||||||
|
|
||||||
// Reset the download state for installation progress
|
|
||||||
if let Ok(mut state) = self.download_state.lock() {
|
if let Ok(mut state) = self.download_state.lock() {
|
||||||
state.progress = 0.0;
|
state.progress = 0.0;
|
||||||
state.completed = false;
|
state.completed = false;
|
||||||
@ -298,6 +287,14 @@ impl SinfarInstallerApp<> {
|
|||||||
state.cancelled = false;
|
state.cancelled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let install_path = self.install_path.clone().expect("Install path should be set");
|
||||||
|
let ee_exe_path = self.ee_exe_path.clone();
|
||||||
|
let game_type = self.game_type.clone().expect("Game type should be set");
|
||||||
|
let download_state = self.download_state.clone();
|
||||||
|
let progress_state = self.download_state.clone();
|
||||||
|
let eframe_ctx = self.eframe_ctx.clone().expect("eframe context should be set");
|
||||||
|
let runtime = self.runtime.clone();
|
||||||
|
|
||||||
// Create extraction manager with progress callback
|
// Create extraction manager with progress callback
|
||||||
let extractor = crate::installer::extractor::ExtractionManager::new(move |progress: f32, _filename: &str, remaining: std::time::Duration| {
|
let extractor = crate::installer::extractor::ExtractionManager::new(move |progress: f32, _filename: &str, remaining: std::time::Duration| {
|
||||||
if let Ok(mut app_state) = progress_state.lock() {
|
if let Ok(mut app_state) = progress_state.lock() {
|
||||||
@ -315,7 +312,7 @@ impl SinfarInstallerApp<> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(files) = downloaded_files {
|
if let Some(files) = downloaded_files {
|
||||||
let download_state = download_state.clone(); // Clone again for the async block
|
let download_state = download_state.clone();
|
||||||
runtime.spawn(async move {
|
runtime.spawn(async move {
|
||||||
// Try to install the files
|
// Try to install the files
|
||||||
if let Err(e) = extractor.install_all_files(
|
if let Err(e) = extractor.install_all_files(
|
||||||
@ -328,10 +325,34 @@ impl SinfarInstallerApp<> {
|
|||||||
app_state.error = Some(format!("Installation failed: {}", e));
|
app_state.error = Some(format!("Installation failed: {}", e));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Mark as complete on success
|
// Create shortcut after successful installation
|
||||||
if let Ok(mut app_state) = download_state.lock() {
|
let shortcut_result = match game_type {
|
||||||
app_state.completed = true;
|
GameType::Diamond => {
|
||||||
app_state.progress = 1.0;
|
// For Diamond, point to sinfarx.exe in install path
|
||||||
|
let target = install_path.join("sinfarx.exe");
|
||||||
|
crate::installer::shortcut::create_shortcut(&target, "Sinfar", None)
|
||||||
|
},
|
||||||
|
GameType::EnhancedEdition => {
|
||||||
|
// For EE, point to sinfarx_ee.exe in bin/win32_8181
|
||||||
|
if let Some(ee_path) = ee_exe_path {
|
||||||
|
let target = ee_path.join("bin").join("win32_8181").join("sinfarx_ee.exe");
|
||||||
|
crate::installer::shortcut::create_shortcut(&target, "Sinfar EE", None)
|
||||||
|
} else {
|
||||||
|
Ok(()) // Should never happen as we validate earlier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(e) = shortcut_result {
|
||||||
|
if let Ok(mut app_state) = download_state.lock() {
|
||||||
|
app_state.error = Some(format!("Failed to create shortcut: {}", e));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Mark as complete on success
|
||||||
|
if let Ok(mut app_state) = download_state.lock() {
|
||||||
|
app_state.completed = true;
|
||||||
|
app_state.progress = 1.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -355,7 +355,7 @@ impl ExtractionManager {
|
|||||||
|
|
||||||
// Extract main content
|
// Extract main content
|
||||||
info!("Starting extraction of main content");
|
info!("Starting extraction of main content");
|
||||||
//self.extract_7z(content_archive, install_path).await?;
|
self.extract_7z(content_archive, install_path).await?;
|
||||||
|
|
||||||
// Handle game-specific files
|
// Handle game-specific files
|
||||||
info!("Processing game-specific files");
|
info!("Processing game-specific files");
|
||||||
|
@ -1,64 +1,62 @@
|
|||||||
pub mod shortcut {
|
use std::path::{Path, PathBuf};
|
||||||
use std::path::{Path, PathBuf};
|
use anyhow::Result;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn create_shortcut(
|
pub fn create_shortcut(
|
||||||
target_path: &Path,
|
target_path: &Path,
|
||||||
shortcut_name: &str,
|
shortcut_name: &str,
|
||||||
icon_path: Option<&Path>,
|
icon_path: Option<&Path>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
use std::os::windows::process::CommandExt;
|
use std::os::windows::process::CommandExt;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
let desktop_path = dirs::desktop_dir().unwrap_or_else(|| PathBuf::from("."));
|
|
||||||
let shortcut_path = desktop_path.join(format!("{}.lnk", shortcut_name));
|
|
||||||
|
|
||||||
let powershell_command = format!(
|
|
||||||
"$s = (New-Object -ComObject WScript.Shell).CreateShortcut('{}'); $s.TargetPath = '{}'; {}; $s.Save()",
|
|
||||||
shortcut_path.to_string_lossy(),
|
|
||||||
target_path.to_string_lossy(),
|
|
||||||
if let Some(icon) = icon_path {
|
|
||||||
format!("$s.IconLocation = '{}'", icon.to_string_lossy())
|
|
||||||
} else {
|
|
||||||
String::new()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
Command::new("powershell")
|
|
||||||
.args(["-Command", &powershell_command])
|
|
||||||
.creation_flags(0x08000000) // CREATE_NO_WINDOW
|
|
||||||
.output()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
let desktop_path = dirs::desktop_dir().unwrap_or_else(|| PathBuf::from("."));
|
||||||
|
let shortcut_path = desktop_path.join(format!("{}.lnk", shortcut_name));
|
||||||
|
|
||||||
|
let powershell_command = format!(
|
||||||
|
"$s = (New-Object -ComObject WScript.Shell).CreateShortcut('{}'); $s.TargetPath = '{}'; {}; $s.Save()",
|
||||||
|
shortcut_path.to_string_lossy(),
|
||||||
|
target_path.to_string_lossy(),
|
||||||
|
if let Some(icon) = icon_path {
|
||||||
|
format!("$s.IconLocation = '{}'", icon.to_string_lossy())
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Command::new("powershell")
|
||||||
|
.args(["-Command", &powershell_command])
|
||||||
|
.creation_flags(0x08000000) // CREATE_NO_WINDOW
|
||||||
|
.output()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
let desktop_path = dirs::desktop_dir().unwrap_or_else(|| PathBuf::from("."));
|
||||||
|
let shortcut_path = desktop_path.join(format!("{}.desktop", shortcut_name));
|
||||||
|
|
||||||
|
let mut desktop_file = std::fs::File::create(shortcut_path)?;
|
||||||
|
|
||||||
|
writeln!(desktop_file, "[Desktop Entry]")?;
|
||||||
|
writeln!(desktop_file, "Type=Application")?;
|
||||||
|
writeln!(desktop_file, "Name={}", shortcut_name)?;
|
||||||
|
writeln!(desktop_file, "Exec={}", target_path.to_string_lossy())?;
|
||||||
|
if let Some(icon) = icon_path {
|
||||||
|
writeln!(desktop_file, "Icon={}", icon.to_string_lossy())?;
|
||||||
|
}
|
||||||
|
writeln!(desktop_file, "Terminal=false")?;
|
||||||
|
|
||||||
|
// Make the .desktop file executable
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
let desktop_path = dirs::desktop_dir().unwrap_or_else(|| PathBuf::from("."));
|
use std::os::unix::fs::PermissionsExt;
|
||||||
let shortcut_path = desktop_path.join(format!("{}.desktop", shortcut_name));
|
let mut perms = std::fs::metadata(&shortcut_path)?.permissions();
|
||||||
|
perms.set_mode(0o755);
|
||||||
let mut desktop_file = std::fs::File::create(shortcut_path)?;
|
std::fs::set_permissions(&shortcut_path, perms)?;
|
||||||
|
|
||||||
writeln!(desktop_file, "[Desktop Entry]")?;
|
|
||||||
writeln!(desktop_file, "Type=Application")?;
|
|
||||||
writeln!(desktop_file, "Name={}", shortcut_name)?;
|
|
||||||
writeln!(desktop_file, "Exec={}", target_path.to_string_lossy())?;
|
|
||||||
if let Some(icon) = icon_path {
|
|
||||||
writeln!(desktop_file, "Icon={}", icon.to_string_lossy())?;
|
|
||||||
}
|
|
||||||
writeln!(desktop_file, "Terminal=false")?;
|
|
||||||
|
|
||||||
// Make the .desktop file executable
|
|
||||||
#[cfg(unix)]
|
|
||||||
{
|
|
||||||
use std::os::unix::fs::PermissionsExt;
|
|
||||||
let mut perms = std::fs::metadata(&shortcut_path)?.permissions();
|
|
||||||
perms.set_mode(0o755);
|
|
||||||
std::fs::set_permissions(&shortcut_path, perms)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user