mirror of https://github.com/ErsatzTV/ErsatzTV.git
Browse Source
* convert windows project from dotnet to rust * update pr jobs * pr job fixes * don't bother building mac app in prs for now * build windows wrapper with rustpull/1088/head
11 changed files with 1229 additions and 139 deletions
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
[package] |
||||
name = "ersatztv_windows" |
||||
version = "0.1.0" |
||||
edition = "2021" |
||||
|
||||
[dependencies] |
||||
tray-item = { git = "https://github.com/olback/tray-item-rs" } |
||||
special-folder = { git = "https://github.com/masinc/special-folder-rs" } |
||||
process_path = "0.1.4" |
||||
|
||||
[dependencies.windows] |
||||
version = "0.43.0" |
||||
features = [ |
||||
"Win32_System_Console", |
||||
"Win32_Foundation" |
||||
] |
||||
|
||||
[build-dependencies] |
||||
windres = "*" |
@ -1,33 +0,0 @@
@@ -1,33 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
||||
<PropertyGroup> |
||||
<OutputType>WinExe</OutputType> |
||||
<TargetFramework>net7.0-windows</TargetFramework> |
||||
<RootNamespace>ErsatzTV_Windows</RootNamespace> |
||||
<Nullable>enable</Nullable> |
||||
<UseWindowsForms>true</UseWindowsForms> |
||||
<ImplicitUsings>enable</ImplicitUsings> |
||||
<ApplicationIcon>Ersatztv.ico</ApplicationIcon> |
||||
</PropertyGroup> |
||||
|
||||
<ItemGroup> |
||||
<Content Include="Ersatztv.ico"> |
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
||||
</Content> |
||||
</ItemGroup> |
||||
|
||||
<ItemGroup> |
||||
<PackageReference Include="CliWrap" Version="3.6.0" /> |
||||
</ItemGroup> |
||||
|
||||
<ItemGroup> |
||||
<ProjectReference Include="..\ErsatzTV.Core\ErsatzTV.Core.csproj" /> |
||||
</ItemGroup> |
||||
|
||||
<ItemGroup> |
||||
<Compile Update="Program.cs"> |
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
||||
</Compile> |
||||
</ItemGroup> |
||||
|
||||
</Project> |
@ -1,14 +0,0 @@
@@ -1,14 +0,0 @@
|
||||
namespace ErsatzTV_Windows; |
||||
|
||||
public static class Program |
||||
{ |
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread] |
||||
public static void Main() |
||||
{ |
||||
ApplicationConfiguration.Initialize(); |
||||
Application.Run(new TrayApplicationContext()); |
||||
} |
||||
} |
@ -1,81 +0,0 @@
@@ -1,81 +0,0 @@
|
||||
using ErsatzTV.Core; |
||||
using System.Diagnostics; |
||||
using CliWrap; |
||||
|
||||
namespace ErsatzTV_Windows; |
||||
|
||||
public class TrayApplicationContext : ApplicationContext |
||||
{ |
||||
private readonly NotifyIcon _trayIcon; |
||||
private readonly CancellationTokenSource _tokenSource; |
||||
|
||||
public TrayApplicationContext() |
||||
{ |
||||
_trayIcon = new NotifyIcon |
||||
{ |
||||
Icon = new Icon("./Ersatztv.ico"), |
||||
ContextMenuStrip = new ContextMenuStrip(), |
||||
Visible = true |
||||
}; |
||||
|
||||
_tokenSource = new CancellationTokenSource(); |
||||
|
||||
AddMenuItem("Launch Web UI", LaunchWebUI); |
||||
AddMenuItem("Show Logs", ShowLogs); |
||||
_trayIcon.ContextMenuStrip.Items.Add(new ToolStripSeparator()); |
||||
AddMenuItem("Exit", Exit); |
||||
|
||||
string folder = AppContext.BaseDirectory; |
||||
string exe = Path.Combine(folder, "ErsatzTV.exe"); |
||||
|
||||
if (File.Exists(exe)) |
||||
{ |
||||
|
||||
Cli.Wrap(exe) |
||||
.WithWorkingDirectory(folder) |
||||
.WithValidation(CommandResultValidation.None) |
||||
.ExecuteAsync(_tokenSource.Token); |
||||
} |
||||
} |
||||
|
||||
private void AddMenuItem(string name, EventHandler action) |
||||
{ |
||||
var item = new ToolStripMenuItem(name); |
||||
item.Click += action; |
||||
_trayIcon.ContextMenuStrip.Items.Add(item); |
||||
} |
||||
|
||||
private void LaunchWebUI(object? sender, EventArgs e) |
||||
{ |
||||
var process = new Process(); |
||||
process.StartInfo.UseShellExecute = true; |
||||
process.StartInfo.FileName = "http://localhost:8409"; |
||||
process.Start(); |
||||
} |
||||
|
||||
private void ShowLogs(object? sender, EventArgs e) |
||||
{ |
||||
if (!Directory.Exists(FileSystemLayout.LogsFolder)) |
||||
{ |
||||
Directory.CreateDirectory(FileSystemLayout.LogsFolder); |
||||
} |
||||
|
||||
var process = new Process(); |
||||
process.StartInfo.UseShellExecute = true; |
||||
process.StartInfo.FileName = FileSystemLayout.LogsFolder; |
||||
process.Start(); |
||||
} |
||||
|
||||
protected override void Dispose(bool disposing) |
||||
{ |
||||
_tokenSource?.Cancel(); |
||||
base.Dispose(disposing); |
||||
} |
||||
|
||||
private void Exit(object? sender, EventArgs e) |
||||
{ |
||||
// Hide tray icon, otherwise it will remain shown until user mouses over it
|
||||
_trayIcon.Visible = false; |
||||
Application.Exit(); |
||||
} |
||||
} |
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
use windres::Build; |
||||
|
||||
fn main() { |
||||
Build::new().compile("ersatztv_windows.rc").unwrap(); |
||||
} |
@ -0,0 +1,2 @@
@@ -0,0 +1,2 @@
|
||||
id ICON "ersatztv.ico" |
||||
ersatztv-icon ICON "ersatztv.ico" |
@ -0,0 +1,101 @@
@@ -0,0 +1,101 @@
|
||||
use special_folder::SpecialFolder; |
||||
use std::fs; |
||||
use std::process::Child; |
||||
use std::process::Command; |
||||
use std::process::Stdio; |
||||
use {std::sync::mpsc, tray_item::TrayItem}; |
||||
use windows::Win32::System::Console; |
||||
|
||||
enum Message { |
||||
Exit, |
||||
} |
||||
|
||||
fn main() { |
||||
let mut tray = TrayItem::new("ErsatzTV", "ersatztv-icon").unwrap(); |
||||
|
||||
let (tx, rx) = mpsc::channel(); |
||||
|
||||
tray.add_menu_item("Launch Web UI", || { |
||||
let _ = Command::new("cmd") |
||||
.arg("/C") |
||||
.arg("start") |
||||
.arg("http://localhost:8409") |
||||
.stdin(Stdio::null()) |
||||
.stdout(Stdio::null()) |
||||
.stderr(Stdio::null()) |
||||
.spawn(); |
||||
}) |
||||
.unwrap(); |
||||
|
||||
tray.add_menu_item("Show Logs", || { |
||||
let path = SpecialFolder::LocalApplicationData |
||||
.get() |
||||
.unwrap() |
||||
.join("ersatztv") |
||||
.join("logs"); |
||||
match path.to_str() { |
||||
None => {} |
||||
Some(folder) => { |
||||
fs::create_dir_all(folder).unwrap(); |
||||
let _ = Command::new("cmd") |
||||
.arg("/C") |
||||
.arg("start") |
||||
.arg(folder) |
||||
.stdin(Stdio::null()) |
||||
.stdout(Stdio::null()) |
||||
.stderr(Stdio::null()) |
||||
.spawn(); |
||||
} |
||||
} |
||||
}) |
||||
.unwrap(); |
||||
|
||||
tray.inner_mut().add_separator().unwrap(); |
||||
|
||||
tray.add_menu_item("Exit", move || { |
||||
tx.send(Message::Exit).unwrap(); |
||||
}) |
||||
.unwrap(); |
||||
|
||||
let path = process_path::get_executable_path(); |
||||
let mut child: Option<Child> = None; |
||||
match path { |
||||
None => {} |
||||
Some(path) => { |
||||
let etv = path.parent().unwrap().join("ErsatzTV.exe"); |
||||
if etv.exists() { |
||||
match etv.to_str() { |
||||
None => {} |
||||
Some(etv) => { |
||||
child = Some( |
||||
Command::new(etv) |
||||
.stdin(Stdio::null()) |
||||
.stdout(Stdio::null()) |
||||
.stderr(Stdio::null()) |
||||
.spawn() |
||||
.unwrap(), |
||||
); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
loop { |
||||
match rx.recv() { |
||||
Ok(Message::Exit) => { |
||||
match child { |
||||
None => {} |
||||
Some(mut child) => { |
||||
unsafe { |
||||
Console::GenerateConsoleCtrlEvent(Console::CTRL_C_EVENT, 0); |
||||
} |
||||
child.wait().unwrap(); |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
_ => {} |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue