mirror of
https://github.com/yusufipk/dikte.git
synced 2026-09-11 10:56:10 +00:00
Keep the two Windows executables from being one file
Windows matches a filename without regard to its case, so Dikte.exe and dikte.exe were one file in the installation directory: PyInstaller wrote the console build second and that is the only one that landed. Every launcher then opened a console window behind the tray, and closing it killed the application. The console one is dikte-cli.exe now, which the setup's shim names. The build reads the PE subsystem of both afterwards, since a filesystem that keeps the two names apart is exactly what the check would run on otherwise.
This commit is contained in:
@@ -45,13 +45,33 @@ $env:DIKTE_ICO = $icon
|
||||
|
||||
# 2. The application --------------------------------------------------------
|
||||
# Two executables in the one directory: Dikte.exe, which is windowed and is
|
||||
# what a shortcut starts, and dikte.exe, which has a console and is what the
|
||||
# `dikte` command runs.
|
||||
# what a shortcut starts, and dikte-cli.exe, which has a console and is what
|
||||
# the `dikte` command runs. Their names differ by more than case on purpose;
|
||||
# Windows would otherwise keep one file for both.
|
||||
& python -m PyInstaller (Join-Path $root "packaging\dikte.spec") `
|
||||
--distpath (Join-Path $build "dist") --workpath (Join-Path $build "work") `
|
||||
--noconfirm --clean
|
||||
if ($LASTEXITCODE -ne 0) { throw "PyInstaller failed" }
|
||||
|
||||
# And the check that the two are really two. Windows matches a filename
|
||||
# without regard to its case, so a rename that leaves them a case apart puts
|
||||
# one file in the directory and whichever was written second is what both
|
||||
# names find. It cost a windowed build once, silently: the machines the
|
||||
# packaging is otherwise checked on all have case-sensitive filesystems, so
|
||||
# this only ever shows up here. Subsystem 2 is windowed, 3 is a console, and
|
||||
# it is the field the loader reads to decide which to give.
|
||||
function Get-PeSubsystem($path) {
|
||||
$bytes = [System.IO.File]::ReadAllBytes($path)
|
||||
$header = [BitConverter]::ToInt32($bytes, 0x3C)
|
||||
return [BitConverter]::ToUInt16($bytes, $header + 0x5C)
|
||||
}
|
||||
foreach ($pair in @(@("Dikte.exe", 2), @("dikte-cli.exe", 3))) {
|
||||
$subsystem = Get-PeSubsystem (Join-Path $dist $pair[0])
|
||||
if ($subsystem -ne $pair[1]) {
|
||||
throw "$($pair[0]) is subsystem $subsystem, expected $($pair[1]): the two executables collided"
|
||||
}
|
||||
}
|
||||
|
||||
# 3. ffmpeg -----------------------------------------------------------------
|
||||
# Recording on Windows goes through ffmpeg's DirectShow input, and Windows
|
||||
# ships nothing like it, so without this the download would be an application
|
||||
|
||||
+3
-3
@@ -84,8 +84,8 @@ Filename: "{app}\Dikte.exe"; Description: "Start Dikte"; \
|
||||
{ The `dikte` command. WindowsApps is already on the user's PATH, so a .cmd
|
||||
left there runs from any terminal without touching the PATH and without an
|
||||
administrator; the alternative is an environment variable edit that every
|
||||
open terminal misses. It names the console executable, which is the one that
|
||||
can print to the terminal it was typed in. }
|
||||
open terminal misses. It names dikte-cli.exe, the console executable, which
|
||||
is the one that can print to the terminal it was typed in. }
|
||||
|
||||
function ShimDir(): String;
|
||||
begin
|
||||
@@ -104,7 +104,7 @@ begin
|
||||
if CurStep = ssPostInstall then begin
|
||||
if DirExists(ShimDir()) then begin
|
||||
Shim := '@echo off' + #13#10
|
||||
+ '"' + ExpandConstant('{app}\dikte.exe') + '" %*' + #13#10;
|
||||
+ '"' + ExpandConstant('{app}\dikte-cli.exe') + '" %*' + #13#10;
|
||||
SaveStringToFile(ShimPath(), Shim, False);
|
||||
end;
|
||||
end;
|
||||
|
||||
@@ -84,12 +84,17 @@ executable = EXE( # noqa: F821
|
||||
# print nothing to it and answer nothing to a script. Everywhere else the one
|
||||
# executable does both jobs: a terminal that started it keeps its output, and
|
||||
# nothing opens a window nobody asked for.
|
||||
#
|
||||
# Named apart from the windowed one rather than `dikte` beside `Dikte`.
|
||||
# Windows matches a filename without regard to its case, so those two are one
|
||||
# file in one directory: whichever PyInstaller writes second is the only one
|
||||
# installed, and a build made on a case-sensitive filesystem never sees it.
|
||||
console_executable = EXE( # noqa: F821
|
||||
archive,
|
||||
analysis.scripts,
|
||||
[],
|
||||
exclude_binaries=True,
|
||||
name="dikte",
|
||||
name="dikte-cli",
|
||||
console=True,
|
||||
target_arch=None,
|
||||
icon=os.environ.get("DIKTE_ICO") or None,
|
||||
|
||||
Reference in New Issue
Block a user