Compare commits
12 Commits
v0.4.5
...
252a3473b3
| Author | SHA1 | Date | |
|---|---|---|---|
| 252a3473b3 | |||
| df6dc2f28c | |||
| defffd0b03 | |||
| 03ba79a8ce | |||
| 168dc9de83 | |||
| 77ddf68c8f | |||
| c682087de8 | |||
| 7250ec8c58 | |||
| 8a4eea282f | |||
| d63ce05d83 | |||
| ec9cf435ca | |||
| 580330b99e |
@@ -16,7 +16,13 @@
|
|||||||
"Bash(curl -s -b /tmp/yf_cookies2.txt -A 'Mozilla/5.0 \\(Windows NT 10.0; Win64; x64\\) AppleWebKit/537.36 \\(KHTML, like Gecko\\) Chrome/120.0.0.0 Safari/537.36' 'https://query1.finance.yahoo.com/v10/finance/quoteSummary/AAPL?modules=cashflowStatementHistory,balanceSheetHistory,calendarEvents&crumb=t5.A45X0LQC')",
|
"Bash(curl -s -b /tmp/yf_cookies2.txt -A 'Mozilla/5.0 \\(Windows NT 10.0; Win64; x64\\) AppleWebKit/537.36 \\(KHTML, like Gecko\\) Chrome/120.0.0.0 Safari/537.36' 'https://query1.finance.yahoo.com/v10/finance/quoteSummary/AAPL?modules=cashflowStatementHistory,balanceSheetHistory,calendarEvents&crumb=t5.A45X0LQC')",
|
||||||
"Bash(curl -s -b /tmp/yf_cookies2.txt -A 'Mozilla/5.0 \\(Windows NT 10.0; Win64; x64\\) AppleWebKit/537.36 \\(KHTML, like Gecko\\) Chrome/120.0.0.0 Safari/537.36' 'https://query1.finance.yahoo.com/v10/finance/quoteSummary/AAPL?modules=financialData,recommendationTrend&crumb=t5.A45X0LQC')",
|
"Bash(curl -s -b /tmp/yf_cookies2.txt -A 'Mozilla/5.0 \\(Windows NT 10.0; Win64; x64\\) AppleWebKit/537.36 \\(KHTML, like Gecko\\) Chrome/120.0.0.0 Safari/537.36' 'https://query1.finance.yahoo.com/v10/finance/quoteSummary/AAPL?modules=financialData,recommendationTrend&crumb=t5.A45X0LQC')",
|
||||||
"Bash(curl -s -b /tmp/yf_cookies2.txt -A 'Mozilla/5.0 \\(Windows NT 10.0; Win64; x64\\) AppleWebKit/537.36 \\(KHTML, like Gecko\\) Chrome/120.0.0.0 Safari/537.36' 'https://query1.finance.yahoo.com/v10/finance/quoteSummary/AAPL?modules=incomeStatementHistoryQuarterly&crumb=t5.A45X0LQC')",
|
"Bash(curl -s -b /tmp/yf_cookies2.txt -A 'Mozilla/5.0 \\(Windows NT 10.0; Win64; x64\\) AppleWebKit/537.36 \\(KHTML, like Gecko\\) Chrome/120.0.0.0 Safari/537.36' 'https://query1.finance.yahoo.com/v10/finance/quoteSummary/AAPL?modules=incomeStatementHistoryQuarterly&crumb=t5.A45X0LQC')",
|
||||||
"Bash(cargo doc *)"
|
"Bash(cargo doc *)",
|
||||||
|
"Bash(git checkout *)",
|
||||||
|
"Bash(git push *)",
|
||||||
|
"Bash(grep -n \"tray_icon::TrayIconEvent\\\\|tray_icon::menu::MenuEvent\\\\|set_event_handler\" ~/.cargo/registry/src/*/tray-icon-0.14*/src/lib.rs 2>/dev/null | head -20)",
|
||||||
|
"Bash(git add *)",
|
||||||
|
"Bash(git commit *)",
|
||||||
|
"Bash(git pull *)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
26
.gitea/workflows/build-check.yml
Normal file
26
.gitea/workflows/build-check.yml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
name: Build Check
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'bug-*'
|
||||||
|
- 'feat-*'
|
||||||
|
- 'dev'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Build check
|
||||||
|
shell: powershell
|
||||||
|
run: cargo build --release
|
||||||
|
|
||||||
|
- name: Report success
|
||||||
|
shell: powershell
|
||||||
|
run: Write-Host "Build succeeded - safe to merge to main"
|
||||||
@@ -16,6 +16,11 @@ jobs:
|
|||||||
shell: powershell
|
shell: powershell
|
||||||
run: cargo build --release
|
run: cargo build --release
|
||||||
|
|
||||||
|
- name: Build installer
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
cargo wix --nocapture
|
||||||
|
|
||||||
- name: Create Gitea Release
|
- name: Create Gitea Release
|
||||||
id: create_release
|
id: create_release
|
||||||
shell: powershell
|
shell: powershell
|
||||||
@@ -38,60 +43,42 @@ jobs:
|
|||||||
} `
|
} `
|
||||||
-Body $body
|
-Body $body
|
||||||
|
|
||||||
"release_id=$($response.id)" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
|
$releaseId = $response.id
|
||||||
|
Write-Host "Created release ID: $releaseId"
|
||||||
|
Add-Content -Path $env:GITHUB_OUTPUT -Value "release_id=$releaseId"
|
||||||
|
|
||||||
- name: Upload binary asset
|
- name: Upload binary asset
|
||||||
shell: powershell
|
shell: powershell
|
||||||
run: |
|
run: |
|
||||||
$releaseId = "${{ steps.create_release.outputs.release_id }}"
|
$releaseId = "${{ steps.create_release.outputs.release_id }}"
|
||||||
$filePath = "target\release\tickr.exe"
|
$filePath = (Resolve-Path "target\release\tickr.exe").Path
|
||||||
|
|
||||||
|
Write-Host "Working dir: $(Get-Location)"
|
||||||
|
Write-Host "Release ID: $releaseId"
|
||||||
|
Write-Host "File: $filePath"
|
||||||
|
|
||||||
|
if (!(Test-Path $filePath)) {
|
||||||
|
Write-Error "File not found: $filePath"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
$uri = "https://gitea.whitlocktech.com/api/v1/repos/whitlocktech/tickr/releases/$releaseId/assets?name=tickr.exe"
|
$uri = "https://gitea.whitlocktech.com/api/v1/repos/whitlocktech/tickr/releases/$releaseId/assets?name=tickr.exe"
|
||||||
|
|
||||||
$fileBytes = [System.IO.File]::ReadAllBytes((Resolve-Path $filePath))
|
& curl.exe -X POST -H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" -F "attachment=@$filePath" "$uri"
|
||||||
$boundary = [System.Guid]::NewGuid().ToString()
|
|
||||||
$LF = "`r`n"
|
- name: Upload installer
|
||||||
|
|
||||||
$bodyLines = @(
|
|
||||||
"--$boundary",
|
|
||||||
"Content-Disposition: form-data; name=`"attachment`"; filename=`"tickr.exe`"",
|
|
||||||
"Content-Type: application/octet-stream",
|
|
||||||
"",
|
|
||||||
[System.Text.Encoding]::Latin1.GetString($fileBytes),
|
|
||||||
"--$boundary--"
|
|
||||||
)
|
|
||||||
|
|
||||||
$bodyBytes = [System.Text.Encoding]::Latin1.GetBytes($bodyLines -join $LF)
|
|
||||||
|
|
||||||
Invoke-RestMethod `
|
|
||||||
-Uri $uri `
|
|
||||||
-Method Post `
|
|
||||||
-Headers @{ Authorization = "token ${{ secrets.RELEASE_TOKEN }}" } `
|
|
||||||
-ContentType "multipart/form-data; boundary=$boundary" `
|
|
||||||
-Body $bodyBytes- name: Upload binary asset
|
|
||||||
shell: powershell
|
shell: powershell
|
||||||
run: |
|
run: |
|
||||||
$releaseId = "${{ steps.create_release.outputs.release_id }}"
|
$releaseId = "${{ steps.create_release.outputs.release_id }}"
|
||||||
$filePath = "target\release\tickr.exe"
|
$msiPath = (Get-ChildItem -Path "target\wix\*.msi" | Select-Object -First 1).FullName
|
||||||
$uri = "https://gitea.whitlocktech.com/api/v1/repos/whitlocktech/tickr/releases/$releaseId/assets?name=tickr.exe"
|
|
||||||
|
Write-Host "MSI Path: $msiPath"
|
||||||
$fileBytes = [System.IO.File]::ReadAllBytes((Resolve-Path $filePath))
|
|
||||||
$boundary = [System.Guid]::NewGuid().ToString()
|
if (!(Test-Path $msiPath)) {
|
||||||
$LF = "`r`n"
|
Write-Error "MSI not found"
|
||||||
|
exit 1
|
||||||
$bodyLines = @(
|
}
|
||||||
"--$boundary",
|
|
||||||
"Content-Disposition: form-data; name=`"attachment`"; filename=`"tickr.exe`"",
|
$uri = "https://gitea.whitlocktech.com/api/v1/repos/whitlocktech/tickr/releases/$releaseId/assets?name=tickr-setup.msi"
|
||||||
"Content-Type: application/octet-stream",
|
|
||||||
"",
|
& curl.exe -X POST -H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" -F "attachment=@$msiPath" "$uri"
|
||||||
[System.Text.Encoding]::Latin1.GetString($fileBytes),
|
|
||||||
"--$boundary--"
|
|
||||||
)
|
|
||||||
|
|
||||||
$bodyBytes = [System.Text.Encoding]::Latin1.GetBytes($bodyLines -join $LF)
|
|
||||||
|
|
||||||
Invoke-RestMethod `
|
|
||||||
-Uri $uri `
|
|
||||||
-Method Post `
|
|
||||||
-Headers @{ Authorization = "token ${{ secrets.RELEASE_TOKEN }}" } `
|
|
||||||
-ContentType "multipart/form-data; boundary=$boundary" `
|
|
||||||
-Body $bodyBytes
|
|
||||||
12
Cargo.toml
12
Cargo.toml
@@ -1,12 +1,18 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tickr"
|
name = "tickr"
|
||||||
version = "0.4.0"
|
version = "0.5.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
authors = ["Whitlocktech"]
|
||||||
|
license = "MIT"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "tickr"
|
name = "tickr"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "tickr-launcher"
|
||||||
|
path = "src/launcher.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
eframe = { version = "0.27", features = ["default"] }
|
eframe = { version = "0.27", features = ["default"] }
|
||||||
egui = "0.27"
|
egui = "0.27"
|
||||||
@@ -19,6 +25,7 @@ anyhow = "1"
|
|||||||
toml = "0.8"
|
toml = "0.8"
|
||||||
dirs = "5"
|
dirs = "5"
|
||||||
semver = "1"
|
semver = "1"
|
||||||
|
winreg = "0.52"
|
||||||
tray-icon = "0.14"
|
tray-icon = "0.14"
|
||||||
image = { version = "0.25", default-features = false, features = ["ico"] }
|
image = { version = "0.25", default-features = false, features = ["ico"] }
|
||||||
|
|
||||||
@@ -30,3 +37,6 @@ strip = true
|
|||||||
|
|
||||||
[target.'cfg(windows)'.build-dependencies]
|
[target.'cfg(windows)'.build-dependencies]
|
||||||
winres = "0.1"
|
winres = "0.1"
|
||||||
|
|
||||||
|
[package.metadata.wix]
|
||||||
|
eula = false
|
||||||
37
src/app.rs
37
src/app.rs
@@ -74,12 +74,16 @@ pub struct TickrApp {
|
|||||||
update_in_progress: bool,
|
update_in_progress: bool,
|
||||||
update_result_rx: mpsc::Receiver<UpdateCheckResult>,
|
update_result_rx: mpsc::Receiver<UpdateCheckResult>,
|
||||||
|
|
||||||
// Tray
|
// Tray — use our own channels fed by set_event_handler so events are
|
||||||
|
// delivered even when the window is hidden (the global receiver() only
|
||||||
|
// works reliably while the winit loop is actively processing messages).
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
tray_icon: Option<tray_icon::TrayIcon>,
|
tray_icon: Option<tray_icon::TrayIcon>,
|
||||||
tray_open_id: Option<tray_icon::menu::MenuId>,
|
tray_open_id: Option<tray_icon::menu::MenuId>,
|
||||||
tray_check_id: Option<tray_icon::menu::MenuId>,
|
tray_check_id: Option<tray_icon::menu::MenuId>,
|
||||||
tray_quit_id: Option<tray_icon::menu::MenuId>,
|
tray_quit_id: Option<tray_icon::menu::MenuId>,
|
||||||
|
tray_ev_rx: mpsc::Receiver<tray_icon::TrayIconEvent>,
|
||||||
|
menu_ev_rx: mpsc::Receiver<tray_icon::menu::MenuEvent>,
|
||||||
window_visible: bool,
|
window_visible: bool,
|
||||||
hide_to_tray: bool,
|
hide_to_tray: bool,
|
||||||
should_quit: bool,
|
should_quit: bool,
|
||||||
@@ -108,6 +112,24 @@ impl TickrApp {
|
|||||||
let (tray_icon, tray_open_id, tray_check_id, tray_quit_id) =
|
let (tray_icon, tray_open_id, tray_check_id, tray_quit_id) =
|
||||||
setup_tray(icon_rgba.clone(), icon_size, watchlist.tickers.len());
|
setup_tray(icon_rgba.clone(), icon_size, watchlist.tickers.len());
|
||||||
|
|
||||||
|
// Route tray events through our own sync channels + wake egui immediately.
|
||||||
|
// SyncSender is Send + Sync, satisfying the 'static closure requirement.
|
||||||
|
// (The global receiver() channel is NOT used — set_event_handler replaces it.)
|
||||||
|
let (tray_ev_tx, tray_ev_rx) = mpsc::sync_channel::<tray_icon::TrayIconEvent>(64);
|
||||||
|
let (menu_ev_tx, menu_ev_rx) = mpsc::sync_channel::<tray_icon::menu::MenuEvent>(64);
|
||||||
|
|
||||||
|
let ctx_tray = cc.egui_ctx.clone();
|
||||||
|
tray_icon::TrayIconEvent::set_event_handler(Some(move |e| {
|
||||||
|
let _ = tray_ev_tx.send(e);
|
||||||
|
ctx_tray.request_repaint();
|
||||||
|
}));
|
||||||
|
|
||||||
|
let ctx_menu = cc.egui_ctx.clone();
|
||||||
|
tray_icon::menu::MenuEvent::set_event_handler(Some(move |e| {
|
||||||
|
let _ = menu_ev_tx.send(e);
|
||||||
|
ctx_menu.request_repaint();
|
||||||
|
}));
|
||||||
|
|
||||||
// Spawn background check task
|
// Spawn background check task
|
||||||
let (bg_cmd_tx, bg_cmd_rx) = tokio::sync::mpsc::unbounded_channel::<BgCmd>();
|
let (bg_cmd_tx, bg_cmd_rx) = tokio::sync::mpsc::unbounded_channel::<BgCmd>();
|
||||||
let (update_result_tx, update_result_rx) = mpsc::channel::<UpdateCheckResult>();
|
let (update_result_tx, update_result_rx) = mpsc::channel::<UpdateCheckResult>();
|
||||||
@@ -138,6 +160,8 @@ impl TickrApp {
|
|||||||
tray_open_id,
|
tray_open_id,
|
||||||
tray_check_id,
|
tray_check_id,
|
||||||
tray_quit_id,
|
tray_quit_id,
|
||||||
|
tray_ev_rx,
|
||||||
|
menu_ev_rx,
|
||||||
window_visible: start_visible,
|
window_visible: start_visible,
|
||||||
hide_to_tray: false,
|
hide_to_tray: false,
|
||||||
should_quit: false,
|
should_quit: false,
|
||||||
@@ -870,17 +894,16 @@ impl TickrApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn poll_tray_events(&mut self, ctx: &Context, _frame: &mut eframe::Frame) {
|
fn poll_tray_events(&mut self, ctx: &Context, _frame: &mut eframe::Frame) {
|
||||||
use tray_icon::TrayIconEvent;
|
// Drain icon-level events (single/double click → show window)
|
||||||
|
while let Ok(event) = self.tray_ev_rx.try_recv() {
|
||||||
while let Ok(event) = TrayIconEvent::receiver().try_recv() {
|
|
||||||
match event {
|
match event {
|
||||||
TrayIconEvent::Click { .. } => self.show_window(ctx),
|
tray_icon::TrayIconEvent::Click { .. } => self.show_window(ctx),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use tray_icon::menu::MenuEvent;
|
// Drain context-menu events
|
||||||
while let Ok(event) = MenuEvent::receiver().try_recv() {
|
while let Ok(event) = self.menu_ev_rx.try_recv() {
|
||||||
if self.tray_open_id.as_ref() == Some(&event.id) {
|
if self.tray_open_id.as_ref() == Some(&event.id) {
|
||||||
self.show_window(ctx);
|
self.show_window(ctx);
|
||||||
} else if self.tray_check_id.as_ref() == Some(&event.id) {
|
} else if self.tray_check_id.as_ref() == Some(&event.id) {
|
||||||
|
|||||||
49
src/launcher.rs
Normal file
49
src/launcher.rs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// tickr-launcher — thin crash-recovery wrapper for tickr.exe
|
||||||
|
//
|
||||||
|
// Spawns tickr.exe from the same directory, watches it, and relaunches on
|
||||||
|
// non-zero exit codes (crashes). A clean exit (code 0) stops the loop so the
|
||||||
|
// user can quit intentionally without the launcher interfering.
|
||||||
|
|
||||||
|
use std::process::Command;
|
||||||
|
use std::thread;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let exe_path = std::env::current_exe()
|
||||||
|
.expect("tickr-launcher: cannot resolve own path");
|
||||||
|
let exe_dir = exe_path
|
||||||
|
.parent()
|
||||||
|
.expect("tickr-launcher: cannot resolve exe directory");
|
||||||
|
let tickr = exe_dir.join("tickr.exe");
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let mut child = match Command::new(&tickr).spawn() {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("tickr-launcher: failed to spawn tickr.exe: {e}");
|
||||||
|
thread::sleep(Duration::from_secs(3));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let status = match child.wait() {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("tickr-launcher: wait() error: {e}");
|
||||||
|
thread::sleep(Duration::from_secs(3));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match status.code() {
|
||||||
|
Some(0) => break, // intentional clean exit — do not relaunch
|
||||||
|
code => {
|
||||||
|
eprintln!(
|
||||||
|
"tickr-launcher: tickr.exe exited with code {:?}, relaunching in 3 s…",
|
||||||
|
code
|
||||||
|
);
|
||||||
|
thread::sleep(Duration::from_secs(3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
34
src/main.rs
34
src/main.rs
@@ -14,7 +14,41 @@ mod watchlist;
|
|||||||
|
|
||||||
pub use version::VERSION;
|
pub use version::VERSION;
|
||||||
|
|
||||||
|
/// Write `HKCU\...\Run\Tickr` pointing to `tickr-launcher.exe` on first launch.
|
||||||
|
/// If the key already exists (any value) it is left untouched.
|
||||||
|
fn ensure_autostart() {
|
||||||
|
use winreg::enums::{HKEY_CURRENT_USER, KEY_READ, KEY_WRITE};
|
||||||
|
use winreg::RegKey;
|
||||||
|
|
||||||
|
let exe_path = match std::env::current_exe() {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
let exe_dir = match exe_path.parent() {
|
||||||
|
Some(d) => d,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
// The launcher watches tickr.exe; autostart should invoke the launcher.
|
||||||
|
let launcher = exe_dir.join("tickr-launcher.exe");
|
||||||
|
let launcher_str = launcher.to_string_lossy().into_owned();
|
||||||
|
|
||||||
|
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
|
||||||
|
let run_key = match hkcu.open_subkey_with_flags(
|
||||||
|
"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
|
||||||
|
KEY_READ | KEY_WRITE,
|
||||||
|
) {
|
||||||
|
Ok(k) => k,
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Only add if not already present
|
||||||
|
if run_key.get_value::<String, _>("Tickr").is_err() {
|
||||||
|
let _ = run_key.set_value("Tickr", &launcher_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() -> eframe::Result<()> {
|
fn main() -> eframe::Result<()> {
|
||||||
|
ensure_autostart();
|
||||||
let config = config::ensure_exists();
|
let config = config::ensure_exists();
|
||||||
|
|
||||||
let (rgba, size) = icon::make_rgba();
|
let (rgba, size) = icon::make_rgba();
|
||||||
|
|||||||
BIN
wix/License.rtf
Normal file
BIN
wix/License.rtf
Normal file
Binary file not shown.
241
wix/main.wxs
Normal file
241
wix/main.wxs
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
<?xml version='1.0' encoding='windows-1252'?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2017 Christopher R. Field.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The "cargo wix" subcommand provides a variety of predefined variables available
|
||||||
|
for customization of this template. The values for each variable are set at
|
||||||
|
installer creation time. The following variables are available:
|
||||||
|
|
||||||
|
TargetTriple = The rustc target triple name.
|
||||||
|
TargetEnv = The rustc target environment. This is typically either
|
||||||
|
"msvc" or "gnu" depending on the toolchain downloaded and
|
||||||
|
installed.
|
||||||
|
TargetVendor = The rustc target vendor. This is typically "pc", but Rust
|
||||||
|
does support other vendors, like "uwp".
|
||||||
|
CargoTargetBinDir = The complete path to the directory containing the
|
||||||
|
binaries (exes) to include. The default would be
|
||||||
|
"target\release\". If an explicit rustc target triple is
|
||||||
|
used, i.e. cross-compiling, then the default path would
|
||||||
|
be "target\<CARGO_TARGET>\<CARGO_PROFILE>",
|
||||||
|
where "<CARGO_TARGET>" is replaced with the "CargoTarget"
|
||||||
|
variable value and "<CARGO_PROFILE>" is replaced with the
|
||||||
|
value from the "CargoProfile" variable. This can also
|
||||||
|
be overridden manually with the "target-bin-dir" flag.
|
||||||
|
CargoTargetDir = The path to the directory for the build artifacts, i.e.
|
||||||
|
"target".
|
||||||
|
CargoProfile = The cargo profile used to build the binaries
|
||||||
|
(usually "debug" or "release").
|
||||||
|
Version = The version for the installer. The default is the
|
||||||
|
"Major.Minor.Fix" semantic versioning number of the Rust
|
||||||
|
package.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Please do not remove these pre-processor If-Else blocks. These are used with
|
||||||
|
the `cargo wix` subcommand to automatically determine the installation
|
||||||
|
destination for 32-bit versus 64-bit installers. Removal of these lines will
|
||||||
|
cause installation errors.
|
||||||
|
-->
|
||||||
|
<?if $(sys.BUILDARCH) = x64 or $(sys.BUILDARCH) = arm64 ?>
|
||||||
|
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
|
||||||
|
<?else ?>
|
||||||
|
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
|
||||||
|
<?endif ?>
|
||||||
|
|
||||||
|
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
|
||||||
|
|
||||||
|
<Product
|
||||||
|
Id='*'
|
||||||
|
Name='tickr'
|
||||||
|
UpgradeCode='52EC33B1-1203-4C27-89BC-82E53707AD5B'
|
||||||
|
Manufacturer='Whitlocktech'
|
||||||
|
Language='1033'
|
||||||
|
Codepage='1252'
|
||||||
|
Version='$(var.Version)'>
|
||||||
|
|
||||||
|
<Package Id='*'
|
||||||
|
Keywords='Installer'
|
||||||
|
Manufacturer='Whitlocktech'
|
||||||
|
InstallerVersion='450'
|
||||||
|
Languages='1033'
|
||||||
|
Compressed='yes'
|
||||||
|
InstallScope='perMachine'
|
||||||
|
SummaryCodepage='1252'
|
||||||
|
/>
|
||||||
|
|
||||||
|
<MajorUpgrade
|
||||||
|
Schedule='afterInstallInitialize'
|
||||||
|
DowngradeErrorMessage='A newer version of [ProductName] is already installed. Setup will now exit.'/>
|
||||||
|
|
||||||
|
<Media Id='1' Cabinet='media1.cab' EmbedCab='yes' DiskPrompt='CD-ROM #1'/>
|
||||||
|
<Property Id='DiskPrompt' Value='tickr Installation'/>
|
||||||
|
|
||||||
|
<Directory Id='TARGETDIR' Name='SourceDir'>
|
||||||
|
<Directory Id='ProgramMenuFolder'>
|
||||||
|
<Directory Id='ApplicationProgramsFolder' Name='Tickr'/>
|
||||||
|
</Directory>
|
||||||
|
<Directory Id='$(var.PlatformProgramFilesFolder)' Name='PFiles'>
|
||||||
|
<Directory Id='APPLICATIONFOLDER' Name='tickr'>
|
||||||
|
<!--
|
||||||
|
Disabling the license sidecar file in the installer is a two step process:
|
||||||
|
|
||||||
|
1. Comment out or remove the `Component` tag along with its contents.
|
||||||
|
2. Comment out or remove the `ComponentRef` tag with the "License" Id
|
||||||
|
attribute value further down in this file.
|
||||||
|
-->
|
||||||
|
<Component Id='License' Guid='*'>
|
||||||
|
<File Id='LicenseFile'
|
||||||
|
DiskId='1'
|
||||||
|
Source='wix\License.rtf'
|
||||||
|
KeyPath='yes'/>
|
||||||
|
</Component>
|
||||||
|
|
||||||
|
<Directory Id='Bin' Name='bin'>
|
||||||
|
<Component Id='Path' Guid='0F04AAC4-3D25-4777-8FBA-77C25BDB274B' KeyPath='yes'>
|
||||||
|
<Environment
|
||||||
|
Id='PATH'
|
||||||
|
Name='PATH'
|
||||||
|
Value='[Bin]'
|
||||||
|
Permanent='no'
|
||||||
|
Part='last'
|
||||||
|
Action='set'
|
||||||
|
System='yes'/>
|
||||||
|
</Component>
|
||||||
|
<Component Id='binary0' Guid='*'>
|
||||||
|
<File
|
||||||
|
Id='exe0'
|
||||||
|
Name='tickr.exe'
|
||||||
|
DiskId='1'
|
||||||
|
Source='$(var.CargoTargetBinDir)\tickr.exe'
|
||||||
|
KeyPath='yes'/>
|
||||||
|
</Component>
|
||||||
|
<Component Id='ApplicationShortcut' Guid='*'>
|
||||||
|
<Shortcut Id='ApplicationStartMenuShortcut'
|
||||||
|
Name='Tickr'
|
||||||
|
Description='Tickr Stock Ticker'
|
||||||
|
Target='[Bin]tickr-launcher.exe'
|
||||||
|
WorkingDirectory='Bin'/>
|
||||||
|
<RemoveFolder Id='CleanUpShortcut' Directory='ApplicationProgramsFolder' On='uninstall'/>
|
||||||
|
<RegistryValue Root='HKCU'
|
||||||
|
Key='Software\Whitlocktech\Tickr'
|
||||||
|
Name='installed'
|
||||||
|
Type='integer'
|
||||||
|
Value='1'
|
||||||
|
KeyPath='yes'/>
|
||||||
|
</Component>
|
||||||
|
</Directory>
|
||||||
|
</Directory>
|
||||||
|
</Directory>
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
<Feature
|
||||||
|
Id='Binaries'
|
||||||
|
Title='Application'
|
||||||
|
Description='Installs all binaries and the license.'
|
||||||
|
Level='1'
|
||||||
|
ConfigurableDirectory='APPLICATIONFOLDER'
|
||||||
|
AllowAdvertise='no'
|
||||||
|
Display='expand'
|
||||||
|
Absent='disallow'>
|
||||||
|
<!--
|
||||||
|
Comment out or remove the following `ComponentRef` tag to remove
|
||||||
|
the license sidecar file from the installer.
|
||||||
|
-->
|
||||||
|
<ComponentRef Id='License'/>
|
||||||
|
|
||||||
|
<ComponentRef Id='binary0'/>
|
||||||
|
<ComponentRef Id='ApplicationShortcut'/>
|
||||||
|
|
||||||
|
<Feature
|
||||||
|
Id='Environment'
|
||||||
|
Title='PATH Environment Variable'
|
||||||
|
Description='Add the install location of the [ProductName] executable to the PATH system environment variable. This allows the [ProductName] executable to be called from any location.'
|
||||||
|
Level='1'
|
||||||
|
Absent='allow'>
|
||||||
|
<ComponentRef Id='Path'/>
|
||||||
|
</Feature>
|
||||||
|
</Feature>
|
||||||
|
|
||||||
|
<SetProperty Id='ARPINSTALLLOCATION' Value='[APPLICATIONFOLDER]' After='CostFinalize'/>
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Uncomment the following `Icon` and `Property` tags to change the product icon.
|
||||||
|
|
||||||
|
The product icon is the graphic that appears in the Add/Remove
|
||||||
|
Programs control panel for the application.
|
||||||
|
-->
|
||||||
|
<!--<Icon Id='ProductICO' SourceFile='wix\Product.ico'/>-->
|
||||||
|
<!--<Property Id='ARPPRODUCTICON' Value='ProductICO' />-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Adding a URL to Add/Remove Programs control panel listing for the
|
||||||
|
application is a two step process:
|
||||||
|
|
||||||
|
1. Uncomment the following `Property` tag with the "ARPHELPLINK" Id
|
||||||
|
attribute value.
|
||||||
|
2. Change the value for `Value` attribute of the following
|
||||||
|
`Property` tag to a valid URL.
|
||||||
|
-->
|
||||||
|
<!--<Property Id='ARPHELPLINK' Value='ChangeMe'/>-->
|
||||||
|
|
||||||
|
<UI>
|
||||||
|
<UIRef Id='WixUI_FeatureTree'/>
|
||||||
|
<!--
|
||||||
|
Disabling the EULA dialog in the installer is a two step process:
|
||||||
|
|
||||||
|
1. Uncomment the following two `Publish` tags
|
||||||
|
2. Comment out or remove the `<WiXVariable Id='WixUILicenseRtf'...` tag further down
|
||||||
|
|
||||||
|
-->
|
||||||
|
<!--<Publish Dialog='WelcomeDlg' Control='Next' Event='NewDialog' Value='CustomizeDlg' Order='99'>1</Publish>-->
|
||||||
|
<!--<Publish Dialog='CustomizeDlg' Control='Back' Event='NewDialog' Value='WelcomeDlg' Order='99'>1</Publish>-->
|
||||||
|
|
||||||
|
</UI>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Disabling the EULA dialog in the installer requires commenting out
|
||||||
|
or removing the following `WixVariable` tag
|
||||||
|
-->
|
||||||
|
<WixVariable Id='WixUILicenseRtf' Value='wix\License.rtf'/>
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Uncomment the next `WixVariable` tag to customize the installer's
|
||||||
|
Graphical User Interface (GUI) and add a custom banner image across
|
||||||
|
the top of each screen. See the WiX Toolset documentation for details
|
||||||
|
about customization.
|
||||||
|
|
||||||
|
The banner BMP dimensions are 493 x 58 pixels.
|
||||||
|
-->
|
||||||
|
<!--<WixVariable Id='WixUIBannerBmp' Value='wix\Banner.bmp'/>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Uncomment the next `WixVariable` tag to customize the installer's
|
||||||
|
Graphical User Interface (GUI) and add a custom image to the first
|
||||||
|
dialog, or screen. See the WiX Toolset documentation for details about
|
||||||
|
customization.
|
||||||
|
|
||||||
|
The dialog BMP dimensions are 493 x 312 pixels.
|
||||||
|
-->
|
||||||
|
<!--<WixVariable Id='WixUIDialogBmp' Value='wix\Dialog.bmp'/>-->
|
||||||
|
|
||||||
|
</Product>
|
||||||
|
|
||||||
|
</Wix>
|
||||||
Reference in New Issue
Block a user