Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ regex = "1"
reqwest = "0.12"
zip = { version = "2.1", default-features = false, features = ["deflate", "time"] }
opener = { version = "0.7", features = ["reveal"] }
chrono = "0.4"
font-kit = "0.14"
base64 = "0.22"
arboard = "3"
Expand All @@ -49,7 +48,6 @@ image = { version = "0.25", default-features = false, features = ["png"] }


[target.'cfg(windows)'.dependencies]
mslnk = "0.1"
winreg = "0.52"
webview2-com = "0.38.2"
windows = "0.61.3"
Expand Down
32 changes: 32 additions & 0 deletions src-tauri/hooks.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,45 @@
; key through SHCTX so it follows `installMode`. Duplicating any of that from
; here overrides a choice the user was already given.

; Drop the uninstall entry a pre-2.7 custom install left in one hive.
;
; Those installs wrote `UninstallString = "…\Markpad.exe" --uninstall` under the
; same key this installer uses. Section Install overwrites that value, but only
; in SHCTX -- so when the old install chose the other hive, its entry survives as
; a second Add/Remove Programs row pointing at a command the binary no longer
; answers. Only the custom installer ever wrote `--uninstall`, so matching on the
; tail of the value cannot hit an entry this installer owns.
;
; DeleteRegKey under HKLM fails without elevation. That is left as a silent
; no-op: the binary forwards a stray `--uninstall` to uninstall.exe on its own,
; which is the same outcome by a slower road.
!macro MARKPAD_DROP_LEGACY_UNINSTALL_ENTRY HIVE
Push $0
Push $1
ClearErrors
ReadRegStr $0 ${HIVE} "${UNINSTKEY}" "UninstallString"
${IfNot} ${Errors}
StrCpy $1 $0 "" -11
${If} $1 == "--uninstall"
DeleteRegKey ${HIVE} "${UNINSTKEY}"
${EndIf}
${EndIf}
Pop $1
Pop $0
!macroend

!macro NSIS_HOOK_POSTINSTALL
; The template registers the file associations through FileAssociation.nsh but
; never inserts that header's own UPDATEFILEASSOC, so Explorer can go on
; serving the previous handler and icon for `.md` until the next logon.
; Broadcasting SHCNE_ASSOCCHANGED (0x08000000) with SHCNF_IDLIST (0) and two
; null items is the documented way to tell it to re-read them.
System::Call 'shell32::SHChangeNotify(i 0x08000000, i 0, p 0, p 0)'

; Section Install has already written the good value into SHCTX by the time
; this hook runs, so neither pass can match the entry that was just written.
!insertmacro MARKPAD_DROP_LEGACY_UNINSTALL_ENTRY HKCU
!insertmacro MARKPAD_DROP_LEGACY_UNINSTALL_ENTRY HKLM
!macroend

!macro NSIS_HOOK_POSTUNINSTALL
Expand Down
54 changes: 26 additions & 28 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,6 @@ fn validate_vsix_archive_limits<R: std::io::Read + std::io::Seek>(
Ok(())
}

mod setup;
mod tab_transfer;
mod window_runtime;
use window_runtime::{AppState, WatcherState};
Expand Down Expand Up @@ -2070,31 +2069,32 @@ fn save_theme(app: AppHandle, theme: String) -> Result<(), String> {
atomic_write(&theme_path, theme.as_bytes()).map_err(|e| e.to_string())
}

#[tauri::command]
async fn get_app_mode() -> String {
let args: Vec<String> = std::env::args().collect();
if args.iter().any(|arg| arg == "--uninstall") {
return "uninstall".to_string();
/// Answer the uninstall entry point that pre-2.7 custom installs left behind.
///
/// Those installs wrote `UninstallString = "…\Markpad.exe" --uninstall`, and
/// Add/Remove Programs still runs it on any machine whose registry entry was
/// never rewritten. The code that used to serve it is gone, so hand the request
/// to the NSIS uninstaller sitting beside us. When there is none to hand it to,
/// fall through and start normally: an editor window is a poor answer, but it
/// is a visible one, and a click that does nothing at all is worse.
#[cfg(target_os = "windows")]
fn forward_legacy_uninstall() {
if !std::env::args().any(|arg| arg == "--uninstall") {
return;
}

let Ok(exe) = std::env::current_exe() else {
return;
};
let Some(uninstaller) = exe.parent().map(|dir| dir.join("uninstall.exe")) else {
return;
};
if !uninstaller.is_file() {
return;
}

let current_exe = std::env::current_exe().unwrap_or_default();
let exe_name = current_exe
.file_name()
.unwrap_or_default()
.to_string_lossy()
.to_lowercase();

let is_installer_mode =
args.iter().any(|arg| arg == "--install") || exe_name.contains("installer");

if setup::is_installed() {
"app".to_string()
} else {
if is_installer_mode {
"installer".to_string()
} else {
"app".to_string()
}
if std::process::Command::new(&uninstaller).spawn().is_ok() {
std::process::exit(0);
}
}

Expand Down Expand Up @@ -2633,6 +2633,8 @@ pub fn run() {

#[cfg(target_os = "windows")]
{
forward_legacy_uninstall();

std::env::set_var(
"WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS",
"--enable-features=SmoothScrolling",
Expand Down Expand Up @@ -2818,10 +2820,6 @@ pub fn run() {
export_pdf_windows,
print_pdf,
save_file_binary,
get_app_mode,
setup::install_app,
setup::uninstall_app,
setup::check_install_status,
is_win11,
open_file_folder,
rename_file,
Expand Down
Loading