Pack static website to windows application with nwjs and nsis under Linux

  1. Copy this script to new files makeinstaller.sh
  2. chmod +x makeinstaller.sh
  3. Execute the script with ./makeinstaller.sh (html files and package.json) (application name)
#!/usr/bin/env bash
set -euo pipefail

# === Проверка на параметри ===
if [ "$#" -lt 2 ]; then
    echo "Използване: $0 <директория_с_играта> <име_на_програмата> [nwjs_version] [--keep-files]"
    exit 1
fi

GAME_DIR="$(realpath "$1")"
APP_NAME="$2"
NW_VERSION="${3:-0.105.0}"  # По подразбиране 0.105.0
KEEP_FILES=false
if [[ "${4:-}" == "--keep-files" ]] || [[ "${3:-}" == "--keep-files" ]]; then
    KEEP_FILES=true
fi

WORK_DIR="$(mktemp -d)"
OUTPUT_DIR="$(pwd)/dist-${APP_NAME}"
NW_DIR="${WORK_DIR}/nwjs"
NW_URL="https://dl.nwjs.io/v${NW_VERSION}/nwjs-v${NW_VERSION}-win-x64.zip"

echo "➡️ Създаване на инсталатор за '${APP_NAME}' от '${GAME_DIR}' с NW.js v${NW_VERSION}"
mkdir -p "$OUTPUT_DIR"

# === 0. Създаване на package.json за fullscreen ===
PACKAGE_JSON="${GAME_DIR}/package.json"
if [[ ! -f "$PACKAGE_JSON" ]]; then
  echo "📄 Създаване на package.json за fullscreen..."
  cat > "$PACKAGE_JSON" <<EOF
{
  "name": "${APP_NAME}",
  "main": "index.html",
  "window": {
    "title": "${APP_NAME}",
    "icon": "icon.ico",
    "fullscreen": true,
    "frame": true,
    "toolbar": false
  }
}
EOF
fi

# === 1. Сваляне и разархивиране на NW.js ===
echo "⬇️ Сваляне на NW.js ${NW_VERSION}..."
wget -q -O "${WORK_DIR}/nwjs.zip" "$NW_URL"
echo "📦 Разархивиране..."
unzip -q "${WORK_DIR}/nwjs.zip" -d "$WORK_DIR"
mv "${WORK_DIR}/nwjs-v${NW_VERSION}-win-x64" "$NW_DIR"

# === 2. Пакетиране на играта в .nw файл ===
echo "🗜️  Пакетиране на играта..."
cd "$GAME_DIR"
zip -rq "${WORK_DIR}/${APP_NAME}.nw" ./*

# === 3. Създаване на изпълним файл (.exe) ===
echo "🔗 Комбиниране на nw.exe с .nw файла..."
cat "${NW_DIR}/nw.exe" "${WORK_DIR}/${APP_NAME}.nw" > "${OUTPUT_DIR}/${APP_NAME}.exe"
chmod +x "${OUTPUT_DIR}/${APP_NAME}.exe"

# === 4. Подготовка на dist директория ===
echo "📁 Подготовка на dist..."
mkdir -p "$OUTPUT_DIR"

# Копиране на нужните файлове от NW.js
for f in \
  "icudtl.dat" \
  "resources.pak" \
  "libEGL.dll" \
  "libGLESv2.dll" \
  "d3dcompiler_47.dll" \
  "nw.dll" \
  "nw_elf.dll" \
  "node.dll" \
  "notification_helper.exe" \
  "nw_100_percent.pak" \
  "nw_200_percent.pak" \
  "vk_swiftshader.dll" \
  "vk_swiftshader_icd.json" \
  "vulkan-1.dll" \
  "ffmpeg.dll" \
  "v8_context_snapshot.bin" \
  "natives_blob.bin"; do
  [ -f "${NW_DIR}/$f" ] && cp "${NW_DIR}/$f" "$OUTPUT_DIR/"
done

# Папки
[ -d "${NW_DIR}/locales" ] && cp -r "${NW_DIR}/locales" "$OUTPUT_DIR/"
[ -d "${NW_DIR}/swiftshader" ] && cp -r "${NW_DIR}/swiftshader" "$OUTPUT_DIR/"

# Добавяне на икона
if [[ -f "$GAME_DIR/icon.ico" ]]; then
  cp "$GAME_DIR/icon.ico" "$OUTPUT_DIR/"
  echo "🖼️ Добавена икона icon.ico"
fi

# === 5. Създаване на NSIS скрипт ===
echo "🧰 Генериране на NSIS инсталатор..."
NSI_FILE="${WORK_DIR}/installer.nsi"
cat > "$NSI_FILE" <<EOF
!define APPNAME "${APP_NAME}"
!define COMPANY "MyCompany"
!define VERSION "${NW_VERSION}"
!define INSTALLDIR "\$APPDATA\\\${COMPANY}\\\${APPNAME}"

Name "\${APPNAME}"
OutFile "${OUTPUT_DIR}/${APP_NAME}-Installer.exe"
InstallDir "\${INSTALLDIR}"

Page directory
Page instfiles
UninstPage uninstConfirm
UninstPage instfiles

Section "Install"
  SetOutPath "\${INSTALLDIR}"
  File /r "${OUTPUT_DIR}\\*.*"
  CreateShortCut "\$DESKTOP\\\${APPNAME}.lnk" "\${INSTALLDIR}\\\${APPNAME}.exe"
  WriteUninstaller "\${INSTALLDIR}\\Uninstall.exe"
SectionEnd

Section "Uninstall"
  Delete "\$DESKTOP\\\${APPNAME}.lnk"
  RMDir /r "\${INSTALLDIR}"
SectionEnd
EOF

# === 6. Компилиране на NSIS инсталатор ===
if command -v makensis >/dev/null 2>&1; then
    echo "🛠️  Компилиране на NSIS инсталатор..."
    makensis "$NSI_FILE" >/dev/null
    echo "✅ Инсталаторът е създаден: ${OUTPUT_DIR}/${APP_NAME}-Installer.exe"
else
    echo "⚠️  NSIS не е инсталиран. Инсталаторният скрипт е в: ${NSI_FILE}"
fi

# === 7. Почистване или оставяне на файловете ===
if [ "$KEEP_FILES" = false ]; then
    echo "🧹 Почистване на временни файлове..."
    rm -rf "$WORK_DIR"
else
    echo "💾 Пазене на временни файлове в: $WORK_DIR"
fi

echo "🎉 Готово!"