Hallo,
in diesem Thread möchte ich für absolute Anfänger mit Inno Setup zeigen, wie ihr für eure Anwendung ganz einfach einen eigenen Installer erstellen könnt, welcher auch die richtige Framework Version mitinstalliert. Aber zuerst wollen wir mal klären, wann ein Setup überhaupt sinnvoll ist und wann nicht. Aber eines möchte ich vorweg nehmen: Erstellt niemals ein Setup, nur weil ihr es als cool empfindet
Wann ist ein Setup sinnvoll:
Wann ein Setup speziell nicht sinnvoll ist:
Ihr dürft in dem Anwendungsordner keine von der Anwendung aus keine Dateien verändern (Config-Dateien speichern o. ä.), weil nicht jeder Nutzer (die wenigsten) im Programme-Ordner durchgehend Schreibrechte haben.
Wenn ihr immer noch der Meinung seit, dass ein Setup sinnvoll ist, kann es losgehen.
Als erstes müsst ihr euch Inno Setup herunterladen. Am besten von der offiziellen Seite, die ihr hier findet: jrsoftware.org/isdl.php
Nachdem ihr das Programm installiert und gestartet habt, begrüßt euch ein Willkommensbildschirm:
Wie in dem Bild markiert wählen wir die Option
Ein Dialog begrüßt euch, auf dem wir die "Weiter"-Schaltfläche anwählen:
Ich denke, das ist selbst erklärend. Wenn alles aufgefüllt ist, gehen wir weiter. Nun dürfen wir wählen, wo die Anwendung hininstalliert werden soll.
Erstmal dürfen wir den Ordner wählen, in welchen unsere Anwendung installiert werden soll. Dann dürfen wir den Namen des Ordners wählen. Als letztes dürfen wir noch auswählen, ob der Benutzer den Ordner ändern darf. Wenn nichts dagegen spricht, sollte diese Option aktiviert sein. Gehen wir weiter.
Jetzt wird es Interessant. Wir dürfen wählen, welche Dateien wohin kopiert werden sollen. Als erstes bestimmen wir die Hauptdatei/unsere Anwendung. Dann fügen wir alle Dateien hinzu, die unsere Anwendung noch so braucht, also dlls usw.
Über Edit könnt ihr bestimmen, in welchen Ordner diese kopiert werden sollen, standardmäßig ist das der Anwendungsordner.
Im Nachfolgenden können wir angeben, welche Lizenz angezeigt werden soll und welche Informationen vor und nach der Installation angezeigt werden sollen. Dies ist optional (wie alles, was nicht fett geschrieben ist).
Nun dürfen wir Sprachen auswählen, die der Benutzer auswählen kann, in denen der Installer übersetzt wird. Theoretisch könnte man einfach alle nehmen, es macht aber Sinn, nur die zu nehmen, in denen das Programm verfügbar ist. Ihr müsst das nicht selbst übersetzten.
Als letztes bestimmen wir die Eigenschaften des Installers. Als erstes dürfen wir den Ordner wählen, in welches das Setup kompiliert werden soll. Dann können wir den Namen der entstehenden Datei bestimmen. Optional können wir ein anderes Icon für den Installer angeben und ein Passwort setzten.
Wir klicken einfach auf
Nun könnt ihr ein Script sehen. Bei genauer Betrachtung werdet ihr sehen, dass es wie eine *.ini-Datei aufgebaut ist. Ihr könnt mit dem grünen Play Button oben in der Menüleiste euren Installer testen und ihr werdet sehen, dass es schon ziemlich fertig aussieht. Jedoch eins fehlt: Das Installieren des .Net Frameworks.
Dafür brauchen wir dieses erstmal. Hier könnt ihr euch zB. den WebInstaller für das .Net Framework 4.5 downloaden: microsoft.com/de-de/download/details.aspx?id=30653
Wenn ihr euch diesen heruntergeladen habt, legt ihn in einem Ordner bei eurem Inno Script ab. In diesem Beispiel legen wir die .Net Framework Installtionsdatei in den Ordner
Nun geht's ans scripten! Dafür müssen wir erstmal die [Code] Region erstellen.
Wir gehen an das Ende der Datei und schreiben dort einfach
Spoiler anzeigen
(Nein, das ist kein C#, aber zumindest ist die Syntax ähnlich)
So sollte es dann aussehen:
Was macht dieser Code?
In diesem Code verstecken sich zwei Prozeduren und zwei Funktionen. Unser Funktion
Unsere Funktion
Als nächstes haben wir die Prozedur
Wenn etwas schief läuft, geben wir eine Meldung aus, dass ein Fehler aufgetreten ist und schließen den Dialog. Das Problem dabei ist, dass der Benutzer normalerweise dann nochmal gefragt wird. Jedoch soll wegen dem Fehler ja nichts mehr weiter installiert werden. Deswegen setzten wir die Variable
Als letztes müssen wir die Methoden nur noch aufrufen. Deswegen gehen wir zu dem
Den Pfad müsst ihr zu dem Pfad eurer .Net Framework Version ändern. Vergesst nicht, dass wenn der Dateiname sich von meinem unterscheidet, diesen auch in der InstallFramework-Methode zu verändern
Wir sagen, dass diese Datei in den TEMP-Ordner entpackt werden soll. Außerdem setzten wir die
Insgesamt könnte eurer Script dann so aussehen:
Spoiler anzeigen
Ich hoffe, dass bei euch alles funktioniert, viel Spaß
in diesem Thread möchte ich für absolute Anfänger mit Inno Setup zeigen, wie ihr für eure Anwendung ganz einfach einen eigenen Installer erstellen könnt, welcher auch die richtige Framework Version mitinstalliert. Aber zuerst wollen wir mal klären, wann ein Setup überhaupt sinnvoll ist und wann nicht. Aber eines möchte ich vorweg nehmen: Erstellt niemals ein Setup, nur weil ihr es als cool empfindet
Wann ist ein Setup sinnvoll:
- Wenn eure Anwendung Registry Änderungen vornehmen muss, wodurch auf die Anwendung verlinkt wird (weil die Anwendung durch das Setup nicht mehr verschoben wird/werden kann)
- Wenn es bekannter wird und sich für eine größere Gruppe außerhalb dieser Community (außerhalb einer Zone von intelligenten Usern) anbietet, denn das ewige "das startet bei mir nicht" von manchen Usern mit einer viel zu niedrigen Framework Version geht auf die nerven. Beachtet aber, dass das genauso nach hinten losgehen kann, denn ich überlege mir bei jedem Installer dreimal, ob ich da auf Weiter klicken soll. Die Alternative wäre, auf der Download Seite überall Anmerkungen zum Downloaden des Frameworks zu machen, obwohl es natürlich Spezialisten gibt, die auch sowas übersehen und dann rummeckern (Ich spreche aus Erfahrung)
Wann ein Setup speziell nicht sinnvoll ist:
- Wenn eure Anwendung nicht so komplex (komplex kann man schwierig definieren, aber in 90 % aller Fälle könnt ihr da mit ja antworten, dass eure Anwendung nicht so komplex ist). Ein Setup stört da nur und blockt Nutzer (wie mich), die sonst gute Kritik da gelassen hätten
Ihr dürft in dem Anwendungsordner keine von der Anwendung aus keine Dateien verändern (Config-Dateien speichern o. ä.), weil nicht jeder Nutzer (die wenigsten) im Programme-Ordner durchgehend Schreibrechte haben.
Wenn ihr immer noch der Meinung seit, dass ein Setup sinnvoll ist, kann es losgehen.
Als erstes müsst ihr euch Inno Setup herunterladen. Am besten von der offiziellen Seite, die ihr hier findet: jrsoftware.org/isdl.php
Nachdem ihr das Programm installiert und gestartet habt, begrüßt euch ein Willkommensbildschirm:
Wie in dem Bild markiert wählen wir die Option
Create a new script file using the Script Wizard
. Durch diese Option wird uns die meiste selbst-schreib-arbeit abgenommen, die wir sonst hätten, wenn wir die erste Option wählen würden.Ein Dialog begrüßt euch, auf dem wir die "Weiter"-Schaltfläche anwählen:
Ich denke, das ist selbst erklärend. Wenn alles aufgefüllt ist, gehen wir weiter. Nun dürfen wir wählen, wo die Anwendung hininstalliert werden soll.
Erstmal dürfen wir den Ordner wählen, in welchen unsere Anwendung installiert werden soll. Dann dürfen wir den Namen des Ordners wählen. Als letztes dürfen wir noch auswählen, ob der Benutzer den Ordner ändern darf. Wenn nichts dagegen spricht, sollte diese Option aktiviert sein. Gehen wir weiter.
Jetzt wird es Interessant. Wir dürfen wählen, welche Dateien wohin kopiert werden sollen. Als erstes bestimmen wir die Hauptdatei/unsere Anwendung. Dann fügen wir alle Dateien hinzu, die unsere Anwendung noch so braucht, also dlls usw.
Über Edit könnt ihr bestimmen, in welchen Ordner diese kopiert werden sollen, standardmäßig ist das der Anwendungsordner.
Im Nachfolgenden können wir angeben, welche Lizenz angezeigt werden soll und welche Informationen vor und nach der Installation angezeigt werden sollen. Dies ist optional (wie alles, was nicht fett geschrieben ist).
Nun dürfen wir Sprachen auswählen, die der Benutzer auswählen kann, in denen der Installer übersetzt wird. Theoretisch könnte man einfach alle nehmen, es macht aber Sinn, nur die zu nehmen, in denen das Programm verfügbar ist. Ihr müsst das nicht selbst übersetzten.
Als letztes bestimmen wir die Eigenschaften des Installers. Als erstes dürfen wir den Ordner wählen, in welches das Setup kompiliert werden soll. Dann können wir den Namen der entstehenden Datei bestimmen. Optional können wir ein anderes Icon für den Installer angeben und ein Passwort setzten.
Wir klicken einfach auf
Next
, lassen die CheckBox angehakt, bestätigen und stellen es fertig.Nun könnt ihr ein Script sehen. Bei genauer Betrachtung werdet ihr sehen, dass es wie eine *.ini-Datei aufgebaut ist. Ihr könnt mit dem grünen Play Button oben in der Menüleiste euren Installer testen und ihr werdet sehen, dass es schon ziemlich fertig aussieht. Jedoch eins fehlt: Das Installieren des .Net Frameworks.
Dafür brauchen wir dieses erstmal. Hier könnt ihr euch zB. den WebInstaller für das .Net Framework 4.5 downloaden: microsoft.com/de-de/download/details.aspx?id=30653
Wenn ihr euch diesen heruntergeladen habt, legt ihn in einem Ordner bei eurem Inno Script ab. In diesem Beispiel legen wir die .Net Framework Installtionsdatei in den Ordner
dependencies
.Nun geht's ans scripten! Dafür müssen wir erstmal die [Code] Region erstellen.
Wir gehen an das Ende der Datei und schreiben dort einfach
[Code]
hin. Wir machen einen Absatz und kopieren diesen Code dahin:C#-Quellcode
- var CancelWithoutPrompt: boolean;
- function InitializeSetup(): Boolean;
- begin
- CancelWithoutPrompt := false;
- result := true;
- end;
- procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
- begin
- if CurPageID=wpInstalling then
- Confirm := not CancelWithoutPrompt;
- end;
- function FrameworkIsNotInstalled: Boolean;
- begin
- Result := RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full');
- end;
- procedure InstallFramework;
- var
- StatusText: string;
- ResultCode: Integer;
- begin
- StatusText := WizardForm.StatusLabel.Caption;
- WizardForm.StatusLabel.Caption := 'Installing .NET framework...';
- WizardForm.ProgressGauge.Style := npbstMarquee;
- try
- if not Exec(ExpandConstant('{tmp}\dotNetFx45_Full_asetup.exe'), '/q /norestart', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
- begin
- // you can interact with the user that the installation failed
- MsgBox('.NET installation failed with code: ' + IntToStr(ResultCode) + '.',
- mbError, MB_OK);
- CancelWithoutPrompt := true;
- WizardForm.Close;
- end;
- finally
- WizardForm.StatusLabel.Caption := StatusText;
- WizardForm.ProgressGauge.Style := npbstNormal;
- end;
- end;
(Nein, das ist kein C#, aber zumindest ist die Syntax ähnlich)
So sollte es dann aussehen:
Was macht dieser Code?
In diesem Code verstecken sich zwei Prozeduren und zwei Funktionen. Unser Funktion
FrameworkIsNotInstalled
gibt einen Boolean zurück, der besagt, ob das Framework mit der Version 4.5 nicht
installiert ist. Es wird überprüft, ob die RegistryValue existiert. Dies müsst ihr bei einer anderen Framework-Version verändern!Unsere Funktion
InitializeSetup
setzt CancelWithoutPrompt
auf false
und sagt, dass alles Ok ist, indem Sie true
zurück gibt. Dies ist ein Ereignis, welches automatisch beim Start von dem Installer ausgeführt wird.Als nächstes haben wir die Prozedur
InstallFramework
, welche wir aufrufen, wenn wir das .Net Framework installieren wollen. Letztendlich startet diese Methode unseren .Net Framework Installer mit den Parametern /q /norestart
. /q steht dafür, dass keine Fragen kommen sollen und das der Installer generell nichts anzeigen soll ("quiet") und /norestart
sollte selbsterklärend sein.Wenn etwas schief läuft, geben wir eine Meldung aus, dass ein Fehler aufgetreten ist und schließen den Dialog. Das Problem dabei ist, dass der Benutzer normalerweise dann nochmal gefragt wird. Jedoch soll wegen dem Fehler ja nichts mehr weiter installiert werden. Deswegen setzten wir die Variable
CancelWithoutPrompt
und reagieren wir auf das CancelButtonClick
-Event, welches aufgerufen wird, wenn der Benutzer auf Abbrechen drückt - oder wir versuchen, das Programm zu schließen. In dieser Methode checken wir die Variable und reagieren dementsprechend mit dem Überspringen der Frage an den Benutzer.Als letztes müssen wir die Methoden nur noch aufrufen. Deswegen gehen wir zu dem
[Files]
-Abschnitt und fügen vor die erste Zeile folgenden Code:Den Pfad müsst ihr zu dem Pfad eurer .Net Framework Version ändern. Vergesst nicht, dass wenn der Dateiname sich von meinem unterscheidet, diesen auch in der InstallFramework-Methode zu verändern
Wir sagen, dass diese Datei in den TEMP-Ordner entpackt werden soll. Außerdem setzten wir die
Flag
, dass die Datei nach der Installation entfernt werden soll. AfterInstall
ist etwas verwirrend. Dies wird aufgerufen, wenn die Datei erfolgreich entpackt wurde, also wenn wir das Framework installieren wollen. Deswegen rufen wir da unsere InstallFramework
-Methode auf. Anschließend setzten wir noch Check
, welches bestimmt, ob dies überhaupt alles stattfinden soll. Check
ruft dann unsere Funktion FrameworkIsNotInstalled
auf, die ja zurückgibt, ob das .Net Framework installiert werden soll.Insgesamt könnte eurer Script dann so aussehen:
C#-Quellcode
- ; Script generated by the Inno Setup Script Wizard.
- ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
- #define MyAppName "Mein Programm"
- #define MyAppVersion "0.1.1"
- #define MyAppPublisher "VincentTB"
- #define MyAppURL "http://www.dasIstMeineSeite.de"
- #define MyAppExeName "Hurricane.exe"
- [Setup]
- ; NOTE: The value of AppId uniquely identifies this application.
- ; Do not use the same AppId value in installers for other applications.
- ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
- AppId={{A1E9462D-9F31-4B26-9413-97F7E70CC3F5}
- AppName={#MyAppName}
- AppVersion={#MyAppVersion}
- ;AppVerName={#MyAppName} {#MyAppVersion}
- AppPublisher={#MyAppPublisher}
- AppPublisherURL={#MyAppURL}
- AppSupportURL={#MyAppURL}
- AppUpdatesURL={#MyAppURL}
- DefaultDirName={pf}\{#MyAppName}
- DefaultGroupName={#MyAppName}
- LicenseFile=D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\LICENSE.txt
- OutputDir=C:\Users\Vincent\Desktop\Neuer Ordner
- OutputBaseFilename=setup
- Compression=lzma
- SolidCompression=yes
- [Languages]
- Name: "english"; MessagesFile: "compiler:Default.isl"
- [Tasks]
- Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
- [Files]
- Source: "dependencies\dotNetFx45_Full_setup.exe"; DestDir: {tmp}; Flags: deleteafterinstall; AfterInstall: InstallFramework; Check: FrameworkIsNotInstalled
- Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\Hurricane.exe"; DestDir: "{app}"; Flags: ignoreversion
- Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\CSCore.dll"; DestDir: "{app}"; Flags: ignoreversion
- Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\Exceptionless.dll"; DestDir: "{app}"; Flags: ignoreversion
- Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\Exceptionless.Models.dll"; DestDir: "{app}"; Flags: ignoreversion
- Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\Exceptionless.Wpf.dll"; DestDir: "{app}"; Flags: ignoreversion
- Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\Newtonsoft.Json.dll"; DestDir: "{app}"; Flags: ignoreversion
- Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\policy.2.0.taglib-sharp.dll"; DestDir: "{app}"; Flags: ignoreversion
- Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\System.Windows.Interactivity.dll"; DestDir: "{app}"; Flags: ignoreversion
- Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\taglib-sharp.dll"; DestDir: "{app}"; Flags: ignoreversion
- Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\updateSystemDotNet.Controller.dll"; DestDir: "{app}"; Flags: ignoreversion
- Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\WPFSoundVisualizationLib.dll"; DestDir: "{app}"; Flags: ignoreversion
- Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\Xceed.Wpf.Toolkit.dll"; DestDir: "{app}"; Flags: ignoreversion
- ; NOTE: Dont use "Flags: ignoreversion" on any shared system files
- [Icons]
- Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
- Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
- [Run]
- Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
- [Code]
- var CancelWithoutPrompt: boolean;
- function InitializeSetup(): Boolean;
- begin
- CancelWithoutPrompt := false;
- result := true;
- end;
- procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
- begin
- if CurPageID=wpInstalling then
- Confirm := not CancelWithoutPrompt;
- end;
- function FrameworkIsNotInstalled: Boolean;
- begin
- Result := not RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full');
- end;
- procedure InstallFramework;
- var
- StatusText: string;
- ResultCode: Integer;
- begin
- StatusText := WizardForm.StatusLabel.Caption;
- WizardForm.StatusLabel.Caption := 'Installing .NET framework...';
- WizardForm.ProgressGauge.Style := npbstMarquee;
- try
- if not Exec(ExpandConstant('{tmp}\dotNetFx45_Full_asetup.exe'), '/q /norestart', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
- begin
- // you can interact with the user that the installation failed
- MsgBox('.NET installation failed with code: ' + IntToStr(ResultCode) + '.',
- mbError, MB_OK);
- CancelWithoutPrompt := true;
- WizardForm.Close;
- end;
- finally
- WizardForm.StatusLabel.Caption := StatusText;
- WizardForm.ProgressGauge.Style := npbstNormal;
- end;
- end;
Ich hoffe, dass bei euch alles funktioniert, viel Spaß
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VincentTB“ ()