Update NSIS installer

- Add manual pages in HTML format and helper for Tesseract command line
- Don't remove the installation directory recursively
- Add GitHub action for Tesseract installer for Windows
- Add docbook-xml to required packages (needed for doc)
- Use unicode for NSIS installer
- Optionally sign executables
- Add more file properties to installer
- Update configuration for use with pacman
- Build Windows installer only for 64 bit Windows

Signed-off-by: Stefan Weil <sw@weilnetz.de>
This commit is contained in:
Stefan Weil 2019-03-16 22:42:34 +01:00
parent b7c5996248
commit d0d43dfbce
6 changed files with 300 additions and 27 deletions

View File

@ -0,0 +1,27 @@
# GitHub actions - Create Tesseract installer for Windows
name: Cross build for Windows
on:
# Trigger workflow in GitHub web frontend or from API.
workflow_dispatch:
inputs:
targets:
description: 'Target operating system'
required: true
default: 'Windows (64 bit)'
type: choice
options:
- 'Windows (64 bit)'
jobs:
build64:
runs-on: [ubuntu-24.04]
steps:
- uses: actions/checkout@v4
- name: Build Tesseract installer (64 bit)
run: nsis/build.sh x86_64
- uses: actions/upload-artifact@v4
with:
name: Tesseract Installer for Windows (64 bit)
path: dist

54
.github/workflows/pkg-config-crosswrapper vendored Executable file
View File

@ -0,0 +1,54 @@
#! /bin/sh
# pkg-config wrapper for cross-building
# Sets pkg-config search path to search multiarch and historical cross-compiling paths.
# If the user has already set PKG_CONFIG_LIBDIR, believe it (even if empty):
# it's documented to be an override
if [ x"${PKG_CONFIG_LIBDIR+set}" = x ]; then
# GNU triplet for the compiler, e.g. i486-linux-gnu for Debian i386,
# i686-linux-gnu for Ubuntu i386
basename="$(basename "$0")"
triplet="${basename%-pkg-config}"
# Normalized multiarch path if any, e.g. i386-linux-gnu for i386
dpkg-architecture >/dev/null 2>&1
if [ "$?" != 0 ]; then
# dpkg-architecture is missing.
echo "Please install dpkg-dev to use pkg-config when cross-building" >&2
exit 1
fi
multiarch="$(dpkg-architecture -t"${triplet}" -qDEB_HOST_MULTIARCH 2>/dev/null)"
# Native multiarch path
native_multiarch="$(cat /usr/lib/pkg-config.multiarch)"
# This can be used for native builds as well, in that case, just exec pkg-config "$@" directly.
if [ "$native_multiarch" = "$multiarch" ]; then
exec pkg-config "$@"
fi
PKG_CONFIG_LIBDIR="/usr/local/${triplet}/lib/pkgconfig"
# For a native build we would also want to append /usr/local/lib/pkgconfig
# at this point; but this is a cross-building script, so don't
PKG_CONFIG_LIBDIR="$PKG_CONFIG_LIBDIR:/usr/local/share/pkgconfig"
if [ -n "$multiarch" ]; then
PKG_CONFIG_LIBDIR="/usr/local/lib/${multiarch}/pkgconfig:$PKG_CONFIG_LIBDIR"
PKG_CONFIG_LIBDIR="$PKG_CONFIG_LIBDIR:/usr/lib/${multiarch}/pkgconfig"
fi
PKG_CONFIG_LIBDIR="$PKG_CONFIG_LIBDIR:/usr/${triplet}/lib/pkgconfig"
# For a native build we would also want to append /usr/lib/pkgconfig
# at this point; but this is a cross-building script, so don't
# If you want to allow use of un-multiarched -dev packages for crossing
# (at the risk of finding build-arch stuff you didn't want, if not in a clean chroot)
# Uncomment the next line:
# PKG_CONFIG_LIBDIR="$PKG_CONFIG_LIBDIR:/usr/lib/pkgconfig"
# ... but on Ubuntu we rely cross-building with non-multiarch libraries:
if dpkg-vendor --derives-from Ubuntu; then
PKG_CONFIG_LIBDIR="$PKG_CONFIG_LIBDIR:/usr/lib/pkgconfig"
fi
PKG_CONFIG_LIBDIR="$PKG_CONFIG_LIBDIR:/usr/share/pkgconfig"
export PKG_CONFIG_LIBDIR
fi
exec pkg-config "$@"

View File

@ -4,7 +4,7 @@ all:
if MINGW if MINGW
gitrev="$(shell git --git-dir=${abs_top_srcdir}/.git --work-tree=${abs_top_srcdir} describe --always --tags)" gitrev="$(shell git --git-dir=${abs_top_srcdir}/.git --work-tree=${abs_top_srcdir} describe --always --tags | sed s/^v//)"
.PHONY: winsetup .PHONY: winsetup
@ -17,6 +17,6 @@ winpath.exe: winpath.cpp
x86_64-w64-mingw32-strip --strip-unneeded $@ x86_64-w64-mingw32-strip --strip-unneeded $@
winsetup: Plugins/x86-unicode/INetC.dll winpath.exe winsetup: Plugins/x86-unicode/INetC.dll winpath.exe
makensis -DCROSSBUILD -DSHARED -DSRCDIR=$(top_srcdir) -DVERSION=${gitrev} $(shell test "$(host_cpu)" = x86_64 && echo "-DW64") -NOCD $(top_srcdir)/nsis/tesseract.nsi makensis -DCROSSBUILD -DSHARED -DSIGNCODE=$(SIGNCODE) -DSRCDIR=$(top_srcdir) -DVERSION=${gitrev} $(shell test "$(host_cpu)" = x86_64 && echo "-DW64") -NOCD $(top_srcdir)/nsis/tesseract.nsi
endif endif

115
nsis/build.sh Executable file
View File

@ -0,0 +1,115 @@
#!/bin/bash
# GitHub actions - Create Tesseract installer for Windows
# Author: Stefan Weil (2010-2024)
set -e
set -x
LANG=C.UTF-8
ARCH=$1
if [ "$ARCH" = "i686" ]; then
MINGW=/mingw32
else
ARCH=x86_64
MINGW=/mingw64
fi
ROOTDIR=$PWD
DISTDIR=$ROOTDIR/dist
HOST=$ARCH-w64-mingw32
TAG=$(cat VERSION).$(date +%Y%m%d)
BUILDDIR=bin/ndebug/$HOST-$TAG
PKG_ARCH=mingw-w64-${ARCH/_/-}
# Install packages.
sudo apt-get update --quiet
sudo apt-get install --assume-yes --no-install-recommends --quiet \
asciidoc xsltproc docbook-xml docbook-xsl \
automake dpkg-dev libtool pkg-config default-jdk-headless \
mingw-w64-tools nsis g++-"$PKG_ARCH" \
makepkg pacman-package-manager
# Install pacman-package-manager and its dependencies (from Ubuntu 22.10).
# sudo curl -Os http://de.archive.ubuntu.com/ubuntu/pool/universe/p/pacman-package-manager/pacman-package-manager_6.0.1-4_amd64.deb
# sudo curl -Os http://de.archive.ubuntu.com/ubuntu/pool/universe/p/pacman-package-manager/libalpm13_6.0.1-4_amd64.deb
# sudo curl -Os http://de.archive.ubuntu.com/ubuntu/pool/universe/p/pacman-package-manager/makepkg_6.0.1-4_amd64.deb
# sudo dpkg -i *.deb || true
# sudo apt-get install --fix-broken --assume-yes --no-install-recommends --quiet
# Configure pacman.
# Enable mirrorlist.
sudo sed -Ei 's/^#.*(Include.*mirrorlist)/\1/' /etc/pacman.conf
(
# Add msys key for pacman.
cd /usr/share/keyrings
sudo curl -Os https://raw.githubusercontent.com/msys2/MSYS2-keyring/master/msys2.gpg
sudo curl -Os https://raw.githubusercontent.com/msys2/MSYS2-keyring/master/msys2-revoked
sudo curl -Os https://raw.githubusercontent.com/msys2/MSYS2-keyring/master/msys2-trusted
)
(
# Add active environments for pacman.
# See https://www.msys2.org/docs/repos-mirrors/.
sudo mkdir -p /etc/pacman.d
cd /etc/pacman.d
cat <<eod | sudo tee mirrorlist >/dev/null
[mingw64]
Include = /etc/pacman.d/mirrorlist.mingw
eod
sudo curl -O https://raw.githubusercontent.com/msys2/MSYS2-packages/master/pacman-mirrors/mirrorlist.mingw
# sudo curl -O https://raw.githubusercontent.com/msys2/MSYS2-packages/master/pacman-mirrors/mirrorlist.msys
)
sudo pacman-key --init
sudo pacman-key --populate msys2
sudo pacman -Syu --noconfirm
# Install required pacman packages.
sudo pacman -S --noconfirm \
mingw-w64-x86_64-curl-winssl \
mingw-w64-x86_64-giflib \
mingw-w64-x86_64-icu \
mingw-w64-x86_64-leptonica \
mingw-w64-x86_64-libarchive \
mingw-w64-x86_64-libidn2 \
mingw-w64-x86_64-openjpeg2 \
mingw-w64-x86_64-openssl \
mingw-w64-x86_64-pango \
mingw-w64-x86_64-libpng \
mingw-w64-x86_64-libtiff \
mingw-w64-x86_64-libwebp
sudo ln -sf "$PWD/.github/workflows/pkg-config-crosswrapper" "/usr/bin/$HOST-pkg-config"
git config --global user.email "sw@weilnetz.de"
git config --global user.name "Stefan Weil"
git tag -a "v$TAG" -m "Tesseract $TAG"
# Run autogen.
./autogen.sh
# Build Tesseract installer.
mkdir -p "$BUILDDIR" && cd "$BUILDDIR"
# Run configure.
PKG_CONFIG_PATH=$MINGW/lib/pkgconfig
export PKG_CONFIG_PATH
# Disable OpenMP (see https://github.com/tesseract-ocr/tesseract/issues/1662).
../../../configure --disable-openmp --host="$HOST" --prefix="/usr/$HOST" \
CXX="$HOST-g++-posix" \
CXXFLAGS="-fno-math-errno -Wall -Wextra -Wpedantic -g -O2 -isystem $MINGW/include" \
LDFLAGS="-L$MINGW/lib"
make all training
MINGW_INSTALL=${PWD}${MINGW}
make install-jars install training-install html prefix="$MINGW_INSTALL"
mkdir -p dll
ln -sv $($ROOTDIR/nsis/find_deps.py $MINGW_INSTALL/bin/*.exe $MINGW_INSTALL/bin/*.dll | sort | uniq) dll/
make winsetup prefix="$MINGW_INSTALL"
# Copy result for upload.
mkdir -p "$DISTDIR" && cp nsis/tesseract-ocr-w*-setup-*.exe "$DISTDIR"

View File

@ -22,10 +22,18 @@
SetCompressor /FINAL /SOLID lzma SetCompressor /FINAL /SOLID lzma
SetCompressorDictSize 32 SetCompressorDictSize 32
Unicode true
; Settings which normally should be passed as command line arguments. ; Settings which normally should be passed as command line arguments.
;define CROSSBUILD ;define CROSSBUILD
;define SHARED ;define SHARED
;define W64 ;define W64
!ifndef COMMENTS
!define COMMENTS "GitHub CI build"
!endif
!ifndef COMPANYNAME
!define COMPANYNAME "Open Source Community"
!endif
!ifndef SRCDIR !ifndef SRCDIR
!define SRCDIR . !define SRCDIR .
!endif !endif
@ -40,7 +48,7 @@ SetCompressorDictSize 32
!define PRODUCT_WEB_SITE "https://github.com/tesseract-ocr/tesseract" !define PRODUCT_WEB_SITE "https://github.com/tesseract-ocr/tesseract"
!endif !endif
!define GITHUB_RAW_FILE_URL \ !define GITHUB_RAW_FILE_URL \
"https://raw.githubusercontent.com/tesseract-ocr/tessdata_fast/master" "https://raw.githubusercontent.com/tesseract-ocr/tessdata_fast/main"
!ifdef CROSSBUILD !ifdef CROSSBUILD
!addincludedir ${SRCDIR}\nsis\include !addincludedir ${SRCDIR}\nsis\include
@ -56,13 +64,17 @@ SetCompressorDictSize 32
!endif !endif
# Name of program and file # Name of program and file
!ifdef VERSION !define OUTFILE "${SETUP}-${VERSION}.exe"
OutFile ${SETUP}-${VERSION}.exe OutFile ${OUTFILE}
!else
OutFile ${SETUP}.exe !ifdef SIGNCODE
!finalize "${SIGNCODE} %1"
!uninstfinalize "${SIGNCODE} %1"
!endif !endif
!define PREFIX "../usr/${ARCH}-w64-mingw32" !ifndef PREFIX
!define PREFIX "../mingw64"
!endif
!define TRAININGDIR "${PREFIX}/bin" !define TRAININGDIR "${PREFIX}/bin"
# General Definitions # General Definitions
@ -72,6 +84,21 @@ Caption "${PRODUCT_NAME} ${VERSION}"
BrandingText /TRIMCENTER "(c) 2010-2019 ${PRODUCT_NAME}" BrandingText /TRIMCENTER "(c) 2010-2019 ${PRODUCT_NAME}"
!endif !endif
; File properties.
!define /date DATEVERSION "%Y%m%d%H%M%S"
VIProductVersion "${VERSION}"
VIAddVersionKey "ProductName" "${PRODUCT_NAME}"
VIAddVersionKey "Comments" "${COMMENTS}"
VIAddVersionKey "CompanyName" "${COMPANYNAME}"
VIAddVersionKey "FileDescription" "Tesseract OCR"
!define /date DATETIME "%Y-%m-%d-%H-%M-%S"
VIAddVersionKey "FileVersion" "${DATETIME}"
VIAddVersionKey "InternalName" "Tesseract"
VIAddVersionKey "LegalCopyright" "Apache-2.0"
#VIAddVersionKey "LegalTrademarks" ""
VIAddVersionKey "OriginalFilename" "${OUTFILE}"
VIAddVersionKey "ProductVersion" "${VERSION}"
!define REGKEY "SOFTWARE\${PRODUCT_NAME}" !define REGKEY "SOFTWARE\${PRODUCT_NAME}"
; HKLM (all users) vs HKCU (current user) defines ; HKLM (all users) vs HKCU (current user) defines
!define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
@ -100,10 +127,12 @@ BrandingText /TRIMCENTER "(c) 2010-2019 ${PRODUCT_NAME}"
!define MUI_FINISHPAGE_LINK "View Tesseract on GitHub" !define MUI_FINISHPAGE_LINK "View Tesseract on GitHub"
!define MUI_FINISHPAGE_LINK_LOCATION "https://github.com/tesseract-ocr/tesseract" !define MUI_FINISHPAGE_LINK_LOCATION "https://github.com/tesseract-ocr/tesseract"
!define MUI_FINISHPAGE_NOAUTOCLOSE !define MUI_FINISHPAGE_NOAUTOCLOSE
!ifdef SHOW_README
; Showing the README does not work. ; Showing the README does not work.
;!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\doc\README.md" !define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\doc\README.md"
;!define MUI_FINISHPAGE_SHOWREADME_FUNCTION ShowReadme !define MUI_FINISHPAGE_SHOWREADME_FUNCTION ShowReadme
;!define MUI_FINISHPAGE_SHOWREADME_TEXT "Show README" !define MUI_FINISHPAGE_SHOWREADME_TEXT "Show README"
!endif
!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM !define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM
!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} !define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY}
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup
@ -128,9 +157,7 @@ Var OLD_KEY
!insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "${SRCDIR}\LICENSE" !insertmacro MUI_PAGE_LICENSE "${SRCDIR}\LICENSE"
!insertmacro MULTIUSER_PAGE_INSTALLMODE !insertmacro MULTIUSER_PAGE_INSTALLMODE
!ifdef VERSION
Page custom PageReinstall PageLeaveReinstall Page custom PageReinstall PageLeaveReinstall
!endif
!insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup !insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup
@ -178,8 +205,10 @@ Section -Main SEC0000
File ${PREFIX}/bin/tesseract.exe File ${PREFIX}/bin/tesseract.exe
File ${PREFIX}/bin/libtesseract-*.dll File ${PREFIX}/bin/libtesseract-*.dll
!ifdef CROSSBUILD !ifdef CROSSBUILD
File ${SRCDIR}\dll\${ARCH}-w64-mingw32\*.dll File ../dll/*.dll
!endif !endif
File winpath.exe
File ../doc/*.html
CreateDirectory "$INSTDIR\tessdata" CreateDirectory "$INSTDIR\tessdata"
SetOutPath "$INSTDIR\tessdata" SetOutPath "$INSTDIR\tessdata"
File ${PREFIX}/share/tessdata/pdf.ttf File ${PREFIX}/share/tessdata/pdf.ttf
@ -245,7 +274,8 @@ SectionEnd
Section "Shortcuts creation" SecCS Section "Shortcuts creation" SecCS
SetOutPath $INSTDIR SetOutPath $INSTDIR
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Console.lnk" $WINDIR\system32\CMD.EXE CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Console.lnk" "$INSTDIR\winpath.exe" "cmd"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Dokumentation.lnk" "$INSTDIR\tesseract.1.html"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Homepage.lnk" "${PRODUCT_WEB_SITE}" CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Homepage.lnk" "${PRODUCT_WEB_SITE}"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\ReadMe.lnk" "${PRODUCT_WEB_SITE}/wiki/ReadMe" CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\ReadMe.lnk" "${PRODUCT_WEB_SITE}/wiki/ReadMe"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\FAQ.lnk" "${PRODUCT_WEB_SITE}/wiki/FAQ" CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\FAQ.lnk" "${PRODUCT_WEB_SITE}/wiki/FAQ"
@ -258,14 +288,12 @@ SectionEnd
SectionGroup "Language data" SecGrp_LD SectionGroup "Language data" SecGrp_LD
Section "English" SecLang_eng Section "English" SecLang_eng
SectionIn RO SectionIn RO
SetOutPath "$INSTDIR\tessdata" !insertmacro Download_Lang_Data eng
File ${SRCDIR}\tessdata\eng.*
SectionEnd SectionEnd
Section "Orientation and script detection" SecLang_osd Section "Orientation and script detection" SecLang_osd
SectionIn 1 SectionIn 1
SetOutPath "$INSTDIR\tessdata" !insertmacro Download_Lang_Data osd
File ${SRCDIR}\tessdata\osd.*
SectionEnd SectionEnd
SectionGroupEnd SectionGroupEnd
@ -466,7 +494,7 @@ SectionGroup "Additional language data (download)" SecGrp_ALD
SectionEnd SectionEnd
; The language names are documented here: ; The language names are documented here:
; https://github.com/tesseract-ocr/tesseract/blob/master/doc/tesseract.1.asc#languages ; https://github.com/tesseract-ocr/tesseract/blob/main/doc/tesseract.1.asc#languages
Section /o "Afrikaans" SecLang_afr Section /o "Afrikaans" SecLang_afr
AddSize 2530 AddSize 2530
@ -588,6 +616,11 @@ SectionGroup "Additional language data (download)" SecGrp_ALD
!insertmacro Download_Lang_Data deu !insertmacro Download_Lang_Data deu
SectionEnd SectionEnd
Section /o "German Fraktur" SecLang_deu_latf
AddSize 6130
!insertmacro Download_Lang_Data deu_latf
SectionEnd
Section /o "Divehi" SecLang_div Section /o "Divehi" SecLang_div
AddSize 1690 AddSize 1690
!insertmacro Download_Lang_Data div !insertmacro Download_Lang_Data div
@ -648,11 +681,6 @@ SectionGroup "Additional language data (download)" SecGrp_ALD
!insertmacro Download_Lang_Data fra !insertmacro Download_Lang_Data fra
SectionEnd SectionEnd
Section /o "German Fraktur" SecLang_frk
AddSize 6130
!insertmacro Download_Lang_Data frk
SectionEnd
Section /o "French - Middle (ca. 1400-1600)" SecLang_frm Section /o "French - Middle (ca. 1400-1600)" SecLang_frm
AddSize 1930 AddSize 1930
!insertmacro Download_Lang_Data frm !insertmacro Download_Lang_Data frm
@ -1130,7 +1158,7 @@ Section -un.Main UNSEC0000
RMDir "$SMPROGRAMS\${PRODUCT_NAME}" RMDir "$SMPROGRAMS\${PRODUCT_NAME}"
DetailPrint "Removing registry info" DetailPrint "Removing registry info"
DeleteRegKey HKLM "Software\Tesseract-OCR" DeleteRegKey HKLM "Software\Tesseract-OCR"
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=1000
# remove the Add/Remove information # remove the Add/Remove information
DeleteRegKey HKLM "${UNINST_KEY}" DeleteRegKey HKLM "${UNINST_KEY}"
@ -1138,7 +1166,15 @@ Section -un.Main UNSEC0000
DeleteRegValue HKLM "${REGKEY}" Path DeleteRegValue HKLM "${REGKEY}" Path
DeleteRegKey /IfEmpty HKLM "${REGKEY}\Components" DeleteRegKey /IfEmpty HKLM "${REGKEY}\Components"
DeleteRegKey /IfEmpty HKLM "${REGKEY}" DeleteRegKey /IfEmpty HKLM "${REGKEY}"
RMDir /r "$INSTDIR" Delete "$INSTDIR\*.dll"
Delete "$INSTDIR\*.exe"
Delete "$INSTDIR\*.html"
Delete "$INSTDIR\doc\AUTHORS"
Delete "$INSTDIR\doc\LICENSE"
Delete "$INSTDIR\doc\README.md"
RMDir "$INSTDIR\doc"
RMDir /r "$INSTDIR\tessdata"
RMDir "$INSTDIR"
SectionEnd SectionEnd
Function PageReinstall Function PageReinstall
@ -1389,10 +1425,12 @@ Function .onInstFailed
MessageBox MB_OK "Installation failed." MessageBox MB_OK "Installation failed."
FunctionEnd FunctionEnd
!ifdef SHOW_README
Function ShowReadme Function ShowReadme
Exec '"wordpad" "doc\README.md"' Exec '"wordpad" "doc\README.md"'
;BringToFront ;BringToFront
FunctionEnd FunctionEnd
!endif
; Prevent running multiple instances of the installer ; Prevent running multiple instances of the installer
Function PreventMultipleInstances Function PreventMultipleInstances

39
nsis/winpath.cpp Normal file
View File

@ -0,0 +1,39 @@
// Copyright (C) 2024 Stefan Weil
//
// SPDX-License-Identifier: Apache-2.0
//
// winpath - run a Windows program with extended PATH
//
// Usage:
//
// winpath [CMD [ARGUMENT ...]]
//
// Example:
//
// winpath cmd
//
// This will start a Windows command line with PATH extended by
// the location of the winpath executable.
#include <process.h> // _spawnvp
#include <stdlib.h> // _putenv_s
#include <string.h> // strcpy, strcat
static char path[4096];
int main(int argc, char *argv[]) {
if (argc > 1) {
char *dir = argv[0];
char *last = strrchr(dir, '\\');
if (last != nullptr) {
*last = '\0';
}
strcpy(path, dir);
strcat(path, ";");
strcat(path, getenv("PATH"));
_putenv_s("PATH", path);
_spawnvp(_P_WAIT, argv[1], argv + 1);
//~ _spawnvp(_P_OVERLAY, argv[1], argv + 1);
}
return 0;
}