mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Create desktop shortcut by default
This commit is contained in:
@@ -168,12 +168,8 @@ fn install_impl(pkg: &bundle::BundleInfo, root_path: &PathBuf, tx: &std::sync::m
|
||||
bail!("The main executable could not be found in the package. Please contact the application author.");
|
||||
}
|
||||
|
||||
info!("Creating start menu shortcut...");
|
||||
let startmenu = w::SHGetKnownFolderPath(&co::KNOWNFOLDERID::StartMenu, co::KF::DONT_UNEXPAND, None)?;
|
||||
let lnk_path = Path::new(&startmenu).join("Programs").join(format!("{}.lnk", &app.title));
|
||||
if let Err(e) = windows::create_lnk(&lnk_path.to_string_lossy(), &main_exe_path, ¤t_path, None) {
|
||||
warn!("Failed to create start menu shortcut: {}", e);
|
||||
}
|
||||
info!("Creating new default shortcuts...");
|
||||
let _ = windows::create_default_lnks(&root_path, &app);
|
||||
|
||||
let ver_string = app.version.to_string();
|
||||
info!("Starting process install hook: \"{}\" --veloapp-install {}", &main_exe_path, &ver_string);
|
||||
|
||||
@@ -8,7 +8,6 @@ use std::{
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use winsafe::{self as w, co};
|
||||
|
||||
pub fn start(wait_for_parent: bool, exe_name: Option<&String>, exe_args: Option<Vec<&str>>, legacy_args: Option<&String>) -> Result<()> {
|
||||
if legacy_args.is_some() && exe_args.is_some() {
|
||||
@@ -86,7 +85,6 @@ fn try_legacy_migration(root_dir: &PathBuf, app: &bundle::Manifest) -> Result<()
|
||||
warn!("This application is installed in a folder prefixed with 'app-'. Attempting to migrate...");
|
||||
let _ = shared::force_stop_package(&root_dir);
|
||||
let current_dir = app.get_current_path(&root_dir);
|
||||
let main_exe_path = app.get_main_exe_path(&root_dir);
|
||||
|
||||
if !Path::new(¤t_dir).exists() {
|
||||
info!("Renaming latest app-* folder to current.");
|
||||
@@ -108,12 +106,8 @@ fn try_legacy_migration(root_dir: &PathBuf, app: &bundle::Manifest) -> Result<()
|
||||
warn!("Failed to remove shortcuts ({}).", e);
|
||||
}
|
||||
|
||||
info!("Creating start menu shortcut...");
|
||||
let startmenu = w::SHGetKnownFolderPath(&co::KNOWNFOLDERID::StartMenu, co::KF::DONT_UNEXPAND, None)?;
|
||||
let lnk_path = Path::new(&startmenu).join("Programs").join(format!("{}.lnk", &app.title));
|
||||
if let Err(e) = windows::create_lnk(&lnk_path.to_string_lossy(), &main_exe_path, ¤t_dir, None) {
|
||||
warn!("Failed to create start menu shortcut: {}", e);
|
||||
}
|
||||
info!("Creating new default shortcuts...");
|
||||
let _ = windows::create_default_lnks(&root_dir, &app);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
use crate::bundle::Manifest;
|
||||
use crate::shared as util;
|
||||
use anyhow::Result;
|
||||
use anyhow::{bail, Result};
|
||||
use glob::glob;
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::Duration;
|
||||
use winsafe::{self as w, co};
|
||||
|
||||
use windows::core::{ComInterface, Result as WindowsResult, GUID, PCWSTR, HSTRING, IntoParam, Param};
|
||||
use windows::core::{ComInterface, IntoParam, Param, Result as WindowsResult, GUID, HSTRING, PCWSTR};
|
||||
use windows::Win32::Foundation::HWND;
|
||||
use windows::Win32::Storage::EnhancedStorage::PKEY_AppUserModel_ID;
|
||||
use windows::Win32::System::Com::StructuredStorage::InitPropVariantFromStringVector;
|
||||
@@ -27,7 +28,43 @@ fn create_instance<T: ComInterface>(clsid: &GUID) -> WindowsResult<T> {
|
||||
unsafe { CoCreateInstance(clsid, None, CLSCTX_ALL) }
|
||||
}
|
||||
|
||||
pub fn create_lnk(output: &str, target: &str, work_dir: &str, app_model_id: Option<&str>) -> WindowsResult<()> {
|
||||
pub fn create_default_lnks(root_path: &PathBuf, app: &Manifest) -> Result<()> {
|
||||
let app = app.clone();
|
||||
let current_path = app.get_current_path(root_path);
|
||||
let main_exe_path = app.get_main_exe_path(root_path);
|
||||
let t = std::thread::spawn(move || {
|
||||
init_com()?;
|
||||
let mut was_error = false;
|
||||
|
||||
info!("Creating desktop shortcut...");
|
||||
let desktop = w::SHGetKnownFolderPath(&co::KNOWNFOLDERID::Desktop, co::KF::DONT_UNEXPAND, None)?;
|
||||
let desktop_lnk = Path::new(&desktop).join(format!("{}.lnk", &app.title));
|
||||
if let Err(e) = _create_lnk(&desktop_lnk.to_string_lossy(), &main_exe_path, ¤t_path, None) {
|
||||
warn!("Failed to create start menu shortcut: {}", e);
|
||||
was_error = true;
|
||||
}
|
||||
|
||||
std::thread::sleep(Duration::from_millis(1));
|
||||
|
||||
info!("Creating start menu shortcut...");
|
||||
let startmenu = w::SHGetKnownFolderPath(&co::KNOWNFOLDERID::StartMenu, co::KF::DONT_UNEXPAND, None)?;
|
||||
let start_lnk = Path::new(&startmenu).join("Programs").join(format!("{}.lnk", &app.title));
|
||||
if let Err(e) = _create_lnk(&start_lnk.to_string_lossy(), &main_exe_path, ¤t_path, None) {
|
||||
warn!("Failed to create start menu shortcut: {}", e);
|
||||
was_error = true;
|
||||
}
|
||||
|
||||
if was_error {
|
||||
bail!("Failed to create one or both default shortcuts");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
});
|
||||
t.join().unwrap()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn create_lnk(output: &str, target: &str, work_dir: &str, app_model_id: Option<&str>) -> WindowsResult<()> {
|
||||
let output = output.to_string();
|
||||
let target = target.to_string();
|
||||
let work_dir = work_dir.to_string();
|
||||
|
||||
@@ -303,13 +303,18 @@ public class WindowsPackTests
|
||||
var argsContent = File.ReadAllText(argsPath).Trim();
|
||||
Assert.Equal("--veloapp-install 1.0.0", argsContent);
|
||||
|
||||
var shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), "Programs", id + ".lnk");
|
||||
Assert.True(File.Exists(shortcutPath));
|
||||
void CheckShortcut(string path)
|
||||
{
|
||||
Assert.True(File.Exists(path));
|
||||
var lnk = new ShellLink(path);
|
||||
Assert.Equal(Path.Combine(tmpInstallDir, "current"), lnk.WorkingDirectory);
|
||||
Assert.Equal(appPath, lnk.Target);
|
||||
}
|
||||
|
||||
var lnk = new ShellLink(shortcutPath);
|
||||
var currentPath = Path.Combine(tmpInstallDir, "current");
|
||||
Assert.Equal(currentPath, lnk.WorkingDirectory);
|
||||
Assert.Equal(appPath, lnk.Target);
|
||||
var startLnk = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), "Programs", id + ".lnk");
|
||||
var desktopLnk = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), id + ".lnk");
|
||||
CheckShortcut(startLnk);
|
||||
CheckShortcut(desktopLnk);
|
||||
|
||||
// check registry exists
|
||||
string installDate = null;
|
||||
@@ -325,7 +330,8 @@ public class WindowsPackTests
|
||||
var uninstOutput = RunNoCoverage(updatePath, new string[] { "--nocolor", "--silent", "--uninstall" }, Environment.CurrentDirectory, logger);
|
||||
Assert.EndsWith(Environment.NewLine + "Y", uninstOutput); // this checks that the self-delete succeeded
|
||||
|
||||
Assert.False(File.Exists(shortcutPath));
|
||||
Assert.False(File.Exists(startLnk));
|
||||
Assert.False(File.Exists(desktopLnk));
|
||||
Assert.False(File.Exists(appPath));
|
||||
|
||||
using (var key2 = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default)
|
||||
|
||||
Reference in New Issue
Block a user