Setup mit automatischer .Net Framework Installation erstellen - mit Inno Setup

    • Allgemein

    Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von slice.

      Setup mit automatischer .Net Framework Installation erstellen - mit Inno Setup

      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:
      • 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
      Was ihr bei einem Setup beachten müsst:
      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:
      Spoiler anzeigen

      C#-Quellcode

      1. var CancelWithoutPrompt: boolean;
      2. function InitializeSetup(): Boolean;
      3. begin
      4. CancelWithoutPrompt := false;
      5. result := true;
      6. end;
      7. procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
      8. begin
      9. if CurPageID=wpInstalling then
      10. Confirm := not CancelWithoutPrompt;
      11. end;
      12. function FrameworkIsNotInstalled: Boolean;
      13. begin
      14. Result := RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full');
      15. end;
      16. procedure InstallFramework;
      17. var
      18. StatusText: string;
      19. ResultCode: Integer;
      20. begin
      21. StatusText := WizardForm.StatusLabel.Caption;
      22. WizardForm.StatusLabel.Caption := 'Installing .NET framework...';
      23. WizardForm.ProgressGauge.Style := npbstMarquee;
      24. try
      25. if not Exec(ExpandConstant('{tmp}\dotNetFx45_Full_asetup.exe'), '/q /norestart', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
      26. begin
      27. // you can interact with the user that the installation failed
      28. MsgBox('.NET installation failed with code: ' + IntToStr(ResultCode) + '.',
      29. mbError, MB_OK);
      30. CancelWithoutPrompt := true;
      31. WizardForm.Close;
      32. end;
      33. finally
      34. WizardForm.StatusLabel.Caption := StatusText;
      35. WizardForm.ProgressGauge.Style := npbstNormal;
      36. end;
      37. 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:

      C#-Quellcode

      1. Source: "dependencies\dotNetFx45_Full_setup.exe"; DestDir: {tmp}; Flags: deleteafterinstall; AfterInstall: InstallFramework; Check: FrameworkIsNotInstalled


      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:
      Spoiler anzeigen

      C#-Quellcode

      1. ; Script generated by the Inno Setup Script Wizard.
      2. ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
      3. #define MyAppName "Mein Programm"
      4. #define MyAppVersion "0.1.1"
      5. #define MyAppPublisher "VincentTB"
      6. #define MyAppURL "http://www.dasIstMeineSeite.de"
      7. #define MyAppExeName "Hurricane.exe"
      8. [Setup]
      9. ; NOTE: The value of AppId uniquely identifies this application.
      10. ; Do not use the same AppId value in installers for other applications.
      11. ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
      12. AppId={{A1E9462D-9F31-4B26-9413-97F7E70CC3F5}
      13. AppName={#MyAppName}
      14. AppVersion={#MyAppVersion}
      15. ;AppVerName={#MyAppName} {#MyAppVersion}
      16. AppPublisher={#MyAppPublisher}
      17. AppPublisherURL={#MyAppURL}
      18. AppSupportURL={#MyAppURL}
      19. AppUpdatesURL={#MyAppURL}
      20. DefaultDirName={pf}\{#MyAppName}
      21. DefaultGroupName={#MyAppName}
      22. LicenseFile=D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\LICENSE.txt
      23. OutputDir=C:\Users\Vincent\Desktop\Neuer Ordner
      24. OutputBaseFilename=setup
      25. Compression=lzma
      26. SolidCompression=yes
      27. [Languages]
      28. Name: "english"; MessagesFile: "compiler:Default.isl"
      29. [Tasks]
      30. Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
      31. [Files]
      32. Source: "dependencies\dotNetFx45_Full_setup.exe"; DestDir: {tmp}; Flags: deleteafterinstall; AfterInstall: InstallFramework; Check: FrameworkIsNotInstalled
      33. Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\Hurricane.exe"; DestDir: "{app}"; Flags: ignoreversion
      34. Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\CSCore.dll"; DestDir: "{app}"; Flags: ignoreversion
      35. Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\Exceptionless.dll"; DestDir: "{app}"; Flags: ignoreversion
      36. Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\Exceptionless.Models.dll"; DestDir: "{app}"; Flags: ignoreversion
      37. Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\Exceptionless.Wpf.dll"; DestDir: "{app}"; Flags: ignoreversion
      38. Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\Newtonsoft.Json.dll"; DestDir: "{app}"; Flags: ignoreversion
      39. Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\policy.2.0.taglib-sharp.dll"; DestDir: "{app}"; Flags: ignoreversion
      40. Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\System.Windows.Interactivity.dll"; DestDir: "{app}"; Flags: ignoreversion
      41. Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\taglib-sharp.dll"; DestDir: "{app}"; Flags: ignoreversion
      42. Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\updateSystemDotNet.Controller.dll"; DestDir: "{app}"; Flags: ignoreversion
      43. Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\WPFSoundVisualizationLib.dll"; DestDir: "{app}"; Flags: ignoreversion
      44. Source: "D:\Dokumente\Visual Studio 2013\Projects\Hurricane\Source\Hurricane\bin\Release\Xceed.Wpf.Toolkit.dll"; DestDir: "{app}"; Flags: ignoreversion
      45. ; NOTE: Dont use "Flags: ignoreversion" on any shared system files
      46. [Icons]
      47. Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
      48. Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
      49. [Run]
      50. Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
      51. [Code]
      52. var CancelWithoutPrompt: boolean;
      53. function InitializeSetup(): Boolean;
      54. begin
      55. CancelWithoutPrompt := false;
      56. result := true;
      57. end;
      58. procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
      59. begin
      60. if CurPageID=wpInstalling then
      61. Confirm := not CancelWithoutPrompt;
      62. end;
      63. function FrameworkIsNotInstalled: Boolean;
      64. begin
      65. Result := not RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full');
      66. end;
      67. procedure InstallFramework;
      68. var
      69. StatusText: string;
      70. ResultCode: Integer;
      71. begin
      72. StatusText := WizardForm.StatusLabel.Caption;
      73. WizardForm.StatusLabel.Caption := 'Installing .NET framework...';
      74. WizardForm.ProgressGauge.Style := npbstMarquee;
      75. try
      76. if not Exec(ExpandConstant('{tmp}\dotNetFx45_Full_asetup.exe'), '/q /norestart', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
      77. begin
      78. // you can interact with the user that the installation failed
      79. MsgBox('.NET installation failed with code: ' + IntToStr(ResultCode) + '.',
      80. mbError, MB_OK);
      81. CancelWithoutPrompt := true;
      82. WizardForm.Close;
      83. end;
      84. finally
      85. WizardForm.StatusLabel.Caption := StatusText;
      86. WizardForm.ProgressGauge.Style := npbstNormal;
      87. end;
      88. end;


      Ich hoffe, dass bei euch alles funktioniert, viel Spaß :)
      Mfg
      Vincent

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VincentTB“ ()

      Da ich mich selbst etwas in IS auskenne, muss ich erst mal sagen, dass das ein schickes Tutorial ist. Ich habe es zwar nicht ausprobiert, aber das werde ich noch nachholen.

      Andere Frage: Ist das dazupacken des Framework-Setups überhaupt legal? Immerhin ist dieses auch Urheberrechtlich geschützt. Ich bin allerdings kein Anwalt und verstehe die Nutzungsbestimmungen nicht ganz. Dort heißt es, die Weitergabe sei untersagt.
      Alle Angaben sind ohne Gewähr, jedoch mit Pistole. Glücksspiel, Drogen und leckeres Essen können süchtig machen.

      43232069737420636f6f6c21
      @masterm
      Keine Ahnung, was du das hat, aber ich glaube, dass es beim .Net Framework etwas anderes ist, denn ohne das geht ja gar nichts.

      Microsoft schrieb:


      Dieser Artikel enthält Links für die Installation von .NET Framework 4.5 und dessen Punktversionen (4.5.1 und 4.5.2) auf Ihrem Computer. Als Entwickler können Sie außerdem .NET Framework über diese Links herunterladen und mit den Apps verteilen.

      Quelle: msdn.microsoft.com/de-de/library/5a4x27ek(v=vs.110).aspx
      Mfg
      Vincent

      Ich habe danach gesucht, aber nichts für Version 4.5 gefunden. Wäre es nicht eine gute Idee, den Link dazu ins Tutorial zu packen? Dann besteht auch nicht die Gefahr, dass das Falsche genommen wird.
      Alle Angaben sind ohne Gewähr, jedoch mit Pistole. Glücksspiel, Drogen und leckeres Essen können süchtig machen.

      43232069737420636f6f6c21
      Ist doch drin:

      VincentTB schrieb:

      ​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


      Oder was meintest du?
      Mfg
      Vincent

      Wie sieht das ganze aus, wenn man ein Update machen möchte ?

      Der Kunde möchte dann nur äußerst ungern alle seine Einstellungen neu machen (weil app.config übergebügelt wurde), evtl. lokale Datenbank-Dateien dürfen nicht angerührt werden usw.
      Auch interessant ist, wie man wohl ein DB-Update machen kann (ein fertiges SQL-Script mit ALTER TABLE-Commands vorausgesetzt).
      Ich weiß dieser Beitrag ist schon einige Monate alt, ich hätte dazu aber zwei kurze fragen:

      1. Welche Dateien braucht das Programm denn alle, um zu laufen? Also neben der .exe Datei aus \bin\release? (benutze keine DLLs von anderen o. ä.)
      2. Die Dateizuordnung, welche man in den Eigenschaften unter "Veröffentlichen" verwenden kann, funktioniert dann damit nicht mehr und man müsste das alternativ erledigen, oder?

      Danke für die Antwort.
      @Sazeidya Probiers doch mal aus. Erstell einen neuen Ordner und kopier da die exe rein. Zum ausführen reichen die dlls und die exe. Du kannst aber auch noch die pdb Datei mitliefern, dann bekommst du mehr Informationen über Fehler (grob gesagt).

      Ich habe die Veröffentlichenfunktion noch nie verwendet, da müsste dir jemand anderes helfen.
      Mfg
      Vincent

      Danke an VincentTB für diesen Beitrag. Ich weiß, dass der Thread Jahre alt ist, aber deswegen im Grunde nicht weniger hilfreich. Bin per Google drauf gestoßen und möchte das Script anwenden.
      Bei mir geht es momentan um .Net 4.8. Ich versuche das Script nachzuvollziehen. Es soll ja auf .Net 4.5 prüfen, aber genau diese Prüfung vermisse ich. Es sieht so aus, als ob auf Version 4 geprüft wird, aber nichts weiter. (Zeile 76) Könnt ihr mir bitte weiterhelfen, wie ich auf Version 4.8 prüfen kann? Version 4.5 oder so hilft mir nicht, da mein Programm auf Basis von 4.8 erstellt wurde.

      Danke euch schonmal.

      Edit: Ich habe das fertige Script mal ausprobiert. ndp48-x86-x64-allos-enu.exe wird entpackt (was eigentlich schonmal nicht passieren sollte, weil .Net 4.8 ja installiert ist) und bricht dann mit folgender Fehlermeldung ab:
      .NET installation failed with code: 2.

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „CodeCreatorX“ ()

      @CodeCreatorX Willkommen im Forum. :thumbup:
      Schau einfach in Deine Rergistry, wie der betreffende Key heißt, editiere das Script entsprechend und feddich.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      Nur leider ist an dieser Registry-Stelle 4.8 nicht aufgeführt …
      Allerdings hab ich einen Key mit dem Pfad HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.8, vielleicht reicht der auch dafür

      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

      Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
      Ich werfe einfach mal folgende Info von Microsoft in den Raum:
      How to: Determine which .NET Framework versions are installed

      Die haben da sogar ein Code Beispiel: Query the registry using code
      Das sollte sich leicht übersetzten lassen.