Vollständige Implementierung des EngineeringSync-Middleware-Tools: - Windows Service (Kestrel :5050) mit FileSystemWatcher + SignalR - WPF Tray-App mit PendingChanges- und Projektverwaltungs-Fenster - Setup-Wizard (8-Schritte-Installer) - SQLite/EF Core Datenschicht (WAL-Modus) - SHA-256-basiertes Debouncing (2s Fenster) - Backup-System mit konfigurierbarer Aufbewahrung Bugfixes & Verbesserungen: - BUG-1: AppDbContext OnConfiguring invertierte Bedingung behoben - BUG-2: Event-Handler-Leak in TrayApp (Fenster-Singleton-Pattern) - BUG-3: ProjectConfigChanged SignalR-Signal in allen CRUD-Endpoints - BUG-5: Rename-Sync löscht alte Datei im Simulations-Ordner - BUG-6: Doppeltes Dispose von SignalR verhindert - BUG-7: Registry-Deinstallation nur EngineeringSync-Eintrag entfernt - S1: Path-Traversal-Schutz via SafeCombine() im SyncManager - E1: FSW Buffer 64KB + automatischer Re-Scan bei Overflow - E2: Retry-Logik (3x) für gesperrte Dateien mit exponentiellem Backoff - E4: Channel.Writer.TryComplete() beim Shutdown - C2: HubMethodNames-Konstanten statt Magic Strings - E3: Pagination in Changes-API (page/pageSize Query-Parameter) - A1: Fire-and-Forget mit try/catch + Logging Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
191 lines
7.0 KiB
Plaintext
191 lines
7.0 KiB
Plaintext
; ======================================================================
|
|
; EngineeringSync - Inno Setup Script
|
|
; Erstellt einen professionellen Windows-Installer (.exe)
|
|
;
|
|
; Voraussetzung: Inno Setup 6.x (https://jrsoftware.org/isinfo.php)
|
|
; Build: .\installer\build-installer.ps1
|
|
; ======================================================================
|
|
|
|
#define AppName "EngineeringSync"
|
|
#define AppVersion "1.0.0"
|
|
#define AppPublisher "EngineeringSync"
|
|
#define AppExe "EngineeringSync.TrayApp.exe"
|
|
#define ServiceExe "EngineeringSync.Service.exe"
|
|
#define SetupExe "EngineeringSync.Setup.exe"
|
|
#define DefaultDir "{autopf}\EngineeringSync"
|
|
#define TrayIcon "..\EngineeringSync.TrayApp\Assets\tray.ico"
|
|
|
|
; -- Pfade zu den publizierten Builds (relative zum .iss-Verzeichnis) --
|
|
#define ServicePublish "..\EngineeringSync.Service\bin\Release\net10.0\publish\"
|
|
#define TrayPublish "..\EngineeringSync.TrayApp\bin\Release\net10.0-windows\publish\"
|
|
#define SetupPublish "..\EngineeringSync.Setup\bin\Release\net10.0-windows\publish\"
|
|
; Self-contained: .NET Runtime wird nicht mehr separat benoetigt
|
|
|
|
|
|
[Setup]
|
|
AppId = {{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}
|
|
AppName = {#AppName}
|
|
AppVersion = {#AppVersion}
|
|
AppPublisher = {#AppPublisher}
|
|
AppPublisherURL = https://github.com/your-org/EngineeringSync
|
|
AppSupportURL = https://github.com/your-org/EngineeringSync/issues
|
|
DefaultDirName = {#DefaultDir}
|
|
DefaultGroupName = {#AppName}
|
|
DisableProgramGroupPage = yes
|
|
PrivilegesRequired = admin
|
|
OutputBaseFilename = EngineeringSync-{#AppVersion}-Setup
|
|
OutputDir = ..\dist
|
|
Compression = lzma2/ultra64
|
|
SolidCompression = yes
|
|
ArchitecturesAllowed = x64compatible
|
|
ArchitecturesInstallIn64BitMode = x64compatible
|
|
|
|
; Installer-Icon (Titelleiste + Explorer)
|
|
SetupIconFile = {#TrayIcon}
|
|
|
|
; Wizard-Design
|
|
WizardStyle = modern
|
|
WizardResizable = no
|
|
WindowVisible = no
|
|
|
|
; Versionsinformationen
|
|
VersionInfoVersion = {#AppVersion}
|
|
VersionInfoCompany = {#AppPublisher}
|
|
VersionInfoDescription = {#AppName} Setup
|
|
VersionInfoProductName = {#AppName}
|
|
|
|
; Deinstallation
|
|
UninstallDisplayName = {#AppName}
|
|
UninstallDisplayIcon = {app}\{#AppExe}
|
|
CreateUninstallRegKey = yes
|
|
|
|
|
|
[Languages]
|
|
Name: "german"; MessagesFile: "compiler:Languages\German.isl"
|
|
|
|
|
|
[Messages]
|
|
WelcomeLabel1=Willkommen beim [name]-Setup-Assistenten
|
|
WelcomeLabel2=Dieser Assistent installiert [name/ver] auf Ihrem Computer.%n%nBitte schließen Sie alle anderen Anwendungen bevor Sie fortfahren.
|
|
FinishedLabel=Die Installation von [name] ist abgeschlossen.%n%nDer Setup-Assistent wird jetzt geöffnet, um Ihre erste Konfiguration einzurichten.
|
|
ClickFinish=Klicken Sie auf Fertigstellen um den EngineeringSync-Konfigurations-Assistenten zu starten.
|
|
|
|
|
|
[Types]
|
|
Name: "full"; Description: "Vollständige Installation"
|
|
Name: "custom"; Description: "Benutzerdefinierte Installation"; Flags: iscustom
|
|
|
|
|
|
[Components]
|
|
Name: "service"; Description: "EngineeringSync Windows-Dienst (erforderlich)"; Types: full custom; Flags: fixed
|
|
Name: "trayapp"; Description: "System Tray Benachrichtigungs-App"; Types: full custom; Flags: fixed
|
|
Name: "setup"; Description: "Konfigurations-Assistent"; Types: full custom; Flags: fixed
|
|
|
|
|
|
[Tasks]
|
|
Name: "desktopicon"; Description: "Desktop-Verknüpfung erstellen"; GroupDescription: "Zusätzliche Symbole:"
|
|
|
|
|
|
[Files]
|
|
; -- Windows Service --
|
|
Source: "{#ServicePublish}*"; DestDir: "{app}"; Components: service; Flags: ignoreversion recursesubdirs
|
|
|
|
; -- TrayApp --
|
|
Source: "{#TrayPublish}*"; DestDir: "{app}"; Components: trayapp; Flags: ignoreversion recursesubdirs
|
|
|
|
; -- Setup-Wizard --
|
|
Source: "{#SetupPublish}*"; DestDir: "{app}"; Components: setup; Flags: ignoreversion recursesubdirs
|
|
|
|
; -- Icons als eigenständige Dateien (für Verknüpfungen) --
|
|
Source: "..\EngineeringSync.TrayApp\Assets\tray.ico"; DestDir: "{app}"; Flags: ignoreversion
|
|
Source: "..\EngineeringSync.Setup\Assets\setup-icon.ico"; DestDir: "{app}"; Flags: ignoreversion
|
|
|
|
|
|
|
|
[Icons]
|
|
; Startmenü - TrayApp
|
|
Name: "{group}\{#AppName}"; Filename: "{app}\{#AppExe}"; IconFilename: "{app}\tray.ico"; Comment: "EngineeringSync Benachrichtigungen"
|
|
|
|
; Startmenü - Konfiguration
|
|
Name: "{group}\{#AppName} konfigurieren"; Filename: "{app}\{#SetupExe}"; IconFilename: "{app}\setup-icon.ico"; Comment: "EngineeringSync konfigurieren"
|
|
|
|
; Startmenü - Deinstallieren
|
|
Name: "{group}\{#AppName} deinstallieren"; Filename: "{uninstallexe}"; IconFilename: "{app}\tray.ico"
|
|
|
|
; Desktop-Verknüpfung (nur wenn Task gewählt)
|
|
Name: "{commondesktop}\{#AppName}"; Filename: "{app}\{#AppExe}"; IconFilename: "{app}\tray.ico"; Comment: "EngineeringSync Benachrichtigungen"; Tasks: desktopicon
|
|
|
|
|
|
[Run]
|
|
; Windows-Dienst registrieren
|
|
Filename: "{sys}\sc.exe"; \
|
|
Parameters: "create EngineeringSync binPath= ""{app}\{#ServiceExe}"" start= auto DisplayName= ""EngineeringSync Watcher Service"""; \
|
|
StatusMsg: "Windows-Dienst wird registriert..."; \
|
|
Flags: runhidden waituntilterminated; \
|
|
Check: not ServiceExists
|
|
|
|
; Konfigurations-Wizard starten (nach der Installation)
|
|
Filename: "{app}\{#SetupExe}"; \
|
|
Description: "EngineeringSync jetzt konfigurieren"; \
|
|
StatusMsg: "Konfigurations-Assistent wird gestartet..."; \
|
|
Flags: postinstall nowait skipifsilent
|
|
|
|
|
|
[UninstallRun]
|
|
; Dienst stoppen
|
|
Filename: "{sys}\sc.exe"; Parameters: "stop EngineeringSync"; \
|
|
Flags: runhidden waituntilterminated; RunOnceId: "StopService"
|
|
|
|
; Dienst löschen
|
|
Filename: "{sys}\sc.exe"; Parameters: "delete EngineeringSync"; \
|
|
Flags: runhidden waituntilterminated; RunOnceId: "DeleteService"
|
|
|
|
; TrayApp beenden
|
|
Filename: "{sys}\taskkill.exe"; Parameters: "/F /IM ""{#AppExe}"""; \
|
|
Flags: runhidden waituntilterminated; RunOnceId: "KillTray"
|
|
|
|
|
|
[UninstallDelete]
|
|
Type: filesandordirs; Name: "{commonappdata}\EngineeringSync"
|
|
|
|
|
|
[Registry]
|
|
; TrayApp-Autostart entfernen bei Deinstallation
|
|
Root: HKCU; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; \
|
|
ValueType: none; ValueName: "EngineeringSync.TrayApp"; Flags: deletevalue uninsdeletevalue
|
|
|
|
|
|
[Code]
|
|
{ ======================================================================
|
|
Pascal-Script
|
|
====================================================================== }
|
|
|
|
function ServiceExists(): Boolean;
|
|
var
|
|
ResultCode: Integer;
|
|
begin
|
|
Exec(ExpandConstant('{sys}\sc.exe'), 'query EngineeringSync',
|
|
'', SW_HIDE, ewWaitUntilTerminated, ResultCode);
|
|
Result := (ResultCode = 0);
|
|
end;
|
|
|
|
{ Upgrade: Bestehende Installation erkennen und stoppen }
|
|
function PrepareToInstall(var NeedsRestart: Boolean): String;
|
|
var
|
|
ResultCode: Integer;
|
|
begin
|
|
Result := '';
|
|
|
|
if ServiceExists() then
|
|
begin
|
|
Exec(ExpandConstant('{sys}\sc.exe'), 'stop EngineeringSync',
|
|
'', SW_HIDE, ewWaitUntilTerminated, ResultCode);
|
|
Sleep(2000);
|
|
end;
|
|
|
|
{ TrayApp beenden falls läuft }
|
|
Exec(ExpandConstant('{sys}\taskkill.exe'),
|
|
'/F /IM "EngineeringSync.TrayApp.exe"',
|
|
'', SW_HIDE, ewWaitUntilTerminated, ResultCode);
|
|
end;
|