.Net Core - App Ordner erstellen

Dieses Thema im Forum "macOS-Developer" wurde erstellt von tightDev, 07.02.19.

  1. tightDev

    tightDev Golden Delicious

    Dabei seit:
    07.02.19
    Beiträge:
    6
    Hi,
    ich such mir n Wolf und finde einfach nichts. Womöglich weil neudeutsch irgendwie alles "App" genannt wird. Dass Apple jetzt auch noch mit "App" startet ist bei den Suchergebnissen auch eher kontraproduktiv.

    Problem ist simpel. Ich habe auf meinem Win7 System eine .Net Core Konsolenanwendung programmiert, meine ersten Schritte mit .Net Core, zugegebenermaßen. Es funktioniert alles. Unter Windows, Linux, MacOS, fast perfekt.

    Aber halt nur fast.

    Ich habe also einen Publish Ordner, da liegt die Startdatei drin, nebst allen Dateien die dafür (möglicherweise) benötigt werden. Als User muss man sich jetzt die Startdatei aus dem Gewühl erst raus suchen. Blöd.

    Also. Wie erstelle ich eine App? Sprich das Verzeichnis "Programmname.App", so dass unter MacOS ein Klick auf den App Ordner die sich darin befindliche Binärdatei ausgeführt wird, ohne den verwirrenden Inhalt anzuzeigen?

    Veröffentlichung im Store, Zertifikate etc. interessiert mich (noch) nicht.
    Ich programmiere zwar schon seit gut 25 Jahren, aber ausschließlich für Windows oder Microcontroller, Mac ist was das angeht für mich neu.

    Falls wer Binaries oder Source braucht (ist OpenSource):
    https://git.tightdev.net/Repository/Tree/bdee314b-c790-4fa9-8349-6b3379691495
     
  2. hosja

    hosja Westfälischer Gülderling

    Dabei seit:
    23.03.07
    Beiträge:
    4.590
    Du kannst dir ja mal ne beliebige Mac Applikation anschauen. Das ist ein Ordner mit ner plist drin und dem executable im macos Ordner.
     
  3. tightDev

    tightDev Golden Delicious

    Dabei seit:
    07.02.19
    Beiträge:
    6
    Ich dachte das wäre klar dass ich das schon gemacht habe, da ich sagte, das .App Verzeichnis (was es im Endeffekt ja auch ist, auch wenn MacOS es anzeigt und handhabt wie Windows eine .exe)...
    Und wo kommen die plist und weitere Dateien nun her? Ich habe keine. Genau das ist doch das Problem... Die Ordnerstruktur kann ich mir zur Not selber zusammen basteln, eine .icns erstellen ist auch kein Ding / schon getan.
     
  4. martinv2

    martinv2 Salvatico di Campascio

    Dabei seit:
    14.04.12
    Beiträge:
    434
    Mit dem Suchbegriff "structure of an app site:developer.apple.com" bei Tante Google ist der erste Treffer bei mir ein Link in den Bundle Programming Guide
     
    hosja gefällt das.
  5. hosja

    hosja Westfälischer Gülderling

    Dabei seit:
    23.03.07
    Beiträge:
    4.590
    Die Struktur erstellt Xcode wenn man Swift programmiert.
    Vielleicht gibt es auch einen Generator für .NetCore?
     
  6. tightDev

    tightDev Golden Delicious

    Dabei seit:
    07.02.19
    Beiträge:
    6
    Leider gibt es noch keinen Generator, zumindest afaik... Und es ist ja nicht so dass ich nicht schon versucht hätte eine plist selbst zu erstellen. Auf den ersten Blick sieht sogar alles gut aus, die Zuweisung vom Icon und Binary klappt auch. Nur die Ausführung leider nicht (also wenn ich auf die App klicke, die Binärdatei in Content selbst gestartet läuft wie gesagt fehlerfrei). Irgendwas muss da noch fehlen.

    Wer selber schauen möchte:
    https://tightdev.net/NumQuiz/NumQuiz.App.zip
     
  7. Marcel Bresink

    Marcel Bresink Safran Pepping

    Dabei seit:
    28.05.04
    Beiträge:
    4.354
    Eine "Konsolenanwendung" ist das, was auf dem Mac "Befehlszeilenprogramm" heißt. Das Programm hat keine grafische Oberfläche, deshalb kann es nicht in Form eines "App Bundles" gepackt werden. Der einzige Weg es aufzurufen, ist eine Befehlszeilenumgebung wie z.B. "Terminal".

    Wenn Du ein Symbol für das Programm haben willst, kannst Du höchstens ein Unix-Shell-Skript schreiben, das Dein Programm aufruft. Dieses Shell-Skript markierst Du dann als Dokument, das mit dem Programm "Terminal" zu öffnen ist.
     
    ottomane und tightDev gefällt das.
  8. tightDev

    tightDev Golden Delicious

    Dabei seit:
    07.02.19
    Beiträge:
    6
    Hmmm... Das erklärt einiges, und weist mich in eine andere Richtung.
    Unix Shell Script ist ja kein Problem. ... naja, mit chmod +x wirds schwierig (Benutzerfreundlichkeit und so). Aber man kann ja auch per AppleScript eine App erstellen, die eine .sh ausführt, somit Konsole. Diese führt dann die .NetCore Konsolenanwendung aus.
    Könnte man auch bestimmt direkt machen, aber über .sh wäre schön. Dann kann ich eine Universallösung machen die auch für andere Anwendungen geht, ich muss dann ja nur noch die .sh anpassen. (ich kompiliere unter Windows, ständig mit Apple Script zu hantieren wäre blöd).

    Soweit richtig gedacht, oder funkt mir wieder etwas in meine Gedanken hinein?
     
  9. Marcel Bresink

    Marcel Bresink Safran Pepping

    Dabei seit:
    28.05.04
    Beiträge:
    4.354
    Das könnte man zwar machen, aber das hilft Dir nicht weiter. Das AppleScript-Programm könnte Dein Programm zwar aufrufen, aber dessen Ein-/Ausgabekanäle nirgendwohin leiten. Es erscheint kein Fenster, in dem Du das Programm in irgendeiner Form sehen könntest.

    Du brauchst zwingend eine Terminal-Emulation, die mit den Ein-/Ausgabedatenströmen, die Dein Programm verarbeitet, etwas anfangen kann. Die einfachste Art das zu machen, wäre wie gesagt ein Dokument für das Programm Terminal, das ein Shell-Skript beinhaltet, das Dein Programm aufruft.

    Terminal hört unter anderem auf den UTI-Dokumententyp "com.apple.terminal.shell-script", der z.B. als Textdatei mit der Dateiendung ".command" oder ".tool" realisiert sein darf.
     
  10. tightDev

    tightDev Golden Delicious

    Dabei seit:
    07.02.19
    Beiträge:
    6
    Doch, es geht, genau so :)
    Ich habe zwar zig Anläufe gebraucht, AppleScript hat mir diverse graue Haare beschert, aber es läuft. Und das auch für andere Anwendungen, ohne dass man einen Mac braucht (außer man will signieren, klar).

    Hier das was ich gemacht habe. Ich verwende [[[ ]]] als Platzhalter! Mehr dazu am Ende.

    1. Loader App erstellen.
    Der Universalität (und weil sie genau dies tut) habe ich sie "ShellExecute" genannt.
    Muss auf Mac geschehen, ich lade den Loader aber in meinem Blog und hier etwas später noch hoch. Alles hier nach kann auch unter Windows oder Linux gemacht werden.

    Apple Script öffnen und ein neues Script erstellen.
    Code:
    tell application "Terminal"
        set current_path to POSIX path of ((path to me as text)) & "Contents/MacOS/"
        activate
        do script "cd " & current_path & " && chmod 744 ./ShellExecute.sh && ./ShellExecute.sh"
    end tell
    Hierfür eine App erstellen (auch das Script speichern, besser isses).
    Was passiert?
    Es wird ein Terminal geöffnet, der Pfad der aktuellen Datei ermittelt und das Terminal aktiviert.
    Danach wird in das Verzeichnis der App gewechselt, das .sh Script bekommt Ausführungsrechte und wird gestartet.

    2. App vorbereiten.
    Apple Script will die Anwendung in der App immer "applet" nennen. Ich habe sie für mich umbenannt in "ShellExecute". Ich habe also "Contents/MacOS/applet" und "Contents/Resources/applet.rsrc" passend umbenannt. Den Ordner Scripts nicht anrühren, die Anderen Dateien hier drin können gelöscht werden. Kann man, muss man aber nicht. Wenn nicht: Nachher aufpassen beim Bearbeiten der .plist Datei!

    3. Info.plist vorbereiten
    Vom Prinzip ist die existierende schon ganz ok. Man möchte sie ja aber vielleicht noch etwas anpassen.
    Hier ist meine. Vorsicht, sie ist als Template verfasst.
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>CFBundleName</key>
        <string>[[[APPNAME]]]</string>
        <key>CFBundleDisplayName</key>
        <string>[[[APPNAME]]]</string>
        <key>CFBundleIdentifier</key>
        <string>[[[IDENTIFIER]]]</string>
        <key>CFBundleVersion</key>
        <string>1</string>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleExecutable</key>
        <string>ShellExecute</string>
        <key>CFBundleDocumentTypes</key>
        <array/>
        <key>CFBundleShortVersionString</key>
        <string>[[[VERSION]]]</string>
        <key>NSHumanReadableCopyright</key>
        <string>[[[COPYRIGHT]]]</string>
        <key>NSMainNubFile</key>
        <string></string>
        <key>NSPrincipalClass</key>
        <string>NSApplication</string>
        <key>CFBundleDevelopmentRegion</key>
        <string>English</string>
        <key>CFBundleIconFile</key>
        <string>[[[APPNAME]]]</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>1.0.0.0</string>
        <key>LSMinimumSystemVersionByArchitecture</key>
        <dict>
            <key>x86_64</key>
            <string>10.6</string>
        </dict>
        <key>LSRequiresCarbon</key>
        <true/>
        <key>LSHasLocalizedDisplayName</key>
        <false/>
    </dict>
    </plist>
    4. ShellExecute.sh erstellen
    Diese Datei wird von dem Apple Script ausgeführt und muss in Contents/MacOS liegen.
    Der Inhalt kann frei definiert werden, allerdings ist er simpel.
    Code:
    #!/bin/sh
    ./[[[APPNAME]]]
    exit
    Was passiert? Es wird einfach die Binärdatei ausgeführt. Das exit danach ist gewollt aber nicht gekonnt, siehe Schlusswort.

    5. Die App als Rohling speichern.
    Diese App ist jetzt unvollständig und nicht lauffähig, sie dient uns aber als Rohling um weitere zu erstellen.
    Alle obigen Schritte müssen ab jetzt nicht mehr wiederholt werden. Ausnahme: Codesigning.

    6. Die App mit Inhalt versorgen
    Eine Kopie des Rohlings erstellen (die spätere App) und passend benennen.
    Ich gehe davon aus, dass die (in diesem Fall .Net Core) Konsolenanwendung bereits für macos-x64 kompiliert und veröffentlicht wurde.
    Den Inhalt des .Net publish Ordners kopieren und im App Verzeichnis unter Contents/MacOS einfügen.

    7. Die App fertigstellen
    Erstellt ein Icon für die App, für MacOS scheint das .icns Format gewünscht. Gibt viele Programme die diese erstellen / umwandeln können, ich hatte Photoline verwendet. Das kommt unter /Contents/Resources/[[[APPNAME]]].icns
    Jetzt müssen nur noch die Dateien /Contents/info.plist und /Contents/MacOS/ShellExecute.sh bearbeitet werden.
    Hat man meine Platzhalter verwendet reicht ein simples suchen - ersetzen im Texteditor oder in einem Script / Programm, falls es automatisiert werden soll.

    Hier die Platzhalter die zu ersetzen sind:
    [[[APPNAME]]] = der Name der Anwendung, gleichzeitig der Name der Startdatei (MyApp)
    [[[IDENTIFIER]]] = der eindeutige Identifizierer (net.example.myapp)
    [[[VERSION]]] = Die Versionsnummer der App (1.0.0)
    [[[COPYRIGHT]]] = Das Copyright (Copyright © 2019 example.com)

    8. Testen.
    Ich kann jetzt nur für mich sprechen, aber bei mir klappte es bei mehreren Testprojekten jedes Mal auf Anhieb.

    Bestimmt lässt sich hier und da noch was optimieren, wie gesagt, MacOS ist in dem Bereich für mich noch neu.
    Aber es läuft. Einziger kleiner Schönheitsfehler: Beendet sich die Anwendung bleibt die Konsole offen. Kann ich mit leben.

    Auf jeden Fall vielen Dank für die Hilfe, auch wenn es "nur" das Umbiegen meiner Gedanken war :)
     

    Anhänge:

    #10 tightDev, 09.02.19
    Zuletzt bearbeitet: 09.02.19
  11. Marcel Bresink

    Marcel Bresink Safran Pepping

    Dabei seit:
    28.05.04
    Beiträge:
    4.354
    Das ist viel zu umständlich. Wie gesagt hätte eine zweizeilige Textdatei mit der Endung ".command" gereicht.
     
  12. tightDev

    tightDev Golden Delicious

    Dabei seit:
    07.02.19
    Beiträge:
    6
    Dann hast du trotzdem kein App Bundle, ob es nun eine .sh oder .command ist ist ja nun kein Unterschied. Da kann ich die Binärdatei auch direkt aus dem Ordner raus suchen und starten. Aber genau das wollte ich wegen der Übersichtlichkeit eben vermeiden.