{"id":55001355,"date":"2022-02-01T00:00:00","date_gmt":"2022-01-31T15:18:42","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1355"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Setup_fuer_AccessApplikationen_Restarbeiten","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/","title":{"rendered":"Setup f&uuml;r Access-Applikationen, Restarbeiten"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg08.met.vgwort.de\/na\/dd4fc42fb3ac4e8c9da48daa394d3dc6\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p>Autor: Christoph J&uuml;ngling, https:\/\/www.juengling-edv.de<\/p>\n<p><b>In diesem Teil widmen wir uns einigen Restarbeiten f&uuml;r das Erstellen eines Setups f&uuml;r Access-Applikationen. Diese Arbeiten sind zwar keineswegs unbedingt notwendig, runden aber unser Setup ab und sorgen daher beim Anwender oder Administrator f&uuml;r ein &#8222;gutes Gef&uuml;hl&#8220;. Wir wollen zun&auml;chst sicherstellen, dass unsere Applikation nicht l&auml;uft, wenn wir sie updaten wollen. Dann unterscheiden wir bei der Installation zwischen Beta- und finaler Version. Und letztlich wollen wir unser Setup dann noch digital signieren.<\/b><\/p>\n<h2>L&auml;uft die Applikation<\/h2>\n<p>Wie k&ouml;nnen wir sicherstellen, dass die Access-Applikation nicht l&auml;uft, wenn wir sie updaten wollen<\/p>\n<h2>Prinzip eines &#8222;Mutex&#8220;<\/h2>\n<p>Sicher haben Sie schon bei Setups bemerkt, dass eine Meldung wie diese kam:<\/p>\n<pre>Das Setup hat festgestellt, dass die Applikation Xyz noch l&auml;uft. Bitte beenden Sie diese und starten Sie dann das Setup erneut.<\/pre>\n<p>Dem Anwender ist das nat&uuml;rlich egal, aber der Entwickler fragt sich unweigerlich: &#8222;Woher wei&szlig; das Setup das eigentlich&#8220; Die Frage ist berechtigt, denn einfach mal &#8222;nachschauen&#8220; ist halt f&uuml;r eine Software nicht ganz so einfach wie f&uuml;r uns.<\/p>\n<p>Das Geheimnis hei&szlig;t &#8222;Mutex&#8220;. Das ist die Kurzform von &#8222;mutual exclusion&#8220;, auf Deutsch &#8222;gegenseitiger Ausschluss&#8220;, eine beeindruckend gute Bezeichnung f&uuml;r diesen Mechanismus.<\/p>\n<p>Denn die Setupdurchf&uuml;hrung und das laufende Programm schlie&szlig;en sich gegenseitig aus. W&auml;hrend die ACCDB aktiv ist, sollte man sie nicht per Setup austauschen.<\/p>\n<p>Um dies zu nutzen, ben&ouml;tigen wir also sowohl in der Applikation als auch im Setup jeweils einen Mechanismus, der den Mutex setzen, l&ouml;schen und &uuml;berpr&uuml;fen kann. Unsere Access-Applikation erzeugt den Mutex beim Start und l&ouml;scht ihn kurz vor dem Ende.<\/p>\n<p>Das Setup wiederum &uuml;berpr&uuml;ft nur, ob es ihn gibt. Falls ja, kommt eine Meldung wie oben gezeigt, falls nein, l&auml;uft das Setup einfach weiter.<\/p>\n<p>Das l&auml;sst sich in InnoSetup sogar soweit automatisieren, dass ein von der Accdb angesto&szlig;enes Update automatisch abl&auml;uft.<\/p>\n<h2>Mutex-Klasse (VBA)<\/h2>\n<p>Mit Hilfe eines kurzen Codesegments schaffen wir es, den Mutex beim Starten unserer Access-Applikation zu erzeugen. Das &uuml;bernimmt in meinen Projekten immer eine Klasse, die ich eigens daf&uuml;r geschrieben habe.<\/p>\n<p>Es m&uuml;sste nat&uuml;rlich keine Klasse sein, eine Sub-Prozedur t&auml;te es auch, aber mit der Klasse haben wir den Vorteil, dass wir mit einer Einheit beide Aktionen erledigen k&ouml;nnen: Erzeugen und L&ouml;schen des Mutex wird innerhalb der Klasse durchgef&uuml;hrt &#8211; und zwar &uuml;ber den Konstruktor <b>Initialize<\/b> und den Destruktor <b>Terminate<\/b> der Klasse.<\/p>\n<p>Zur Integration in die Applikation m&uuml;ssen neben der Klasse selbst nur noch eine Deklaration und zwei Zeilen Code eingef&uuml;gt werden.<\/p>\n<p>Schauen wir uns zun&auml;chst die Mutex-Klasse an. Besonders aufw&auml;ndig ist sie nicht (siehe Listing 1).<\/p>\n<pre>''''\r\n'' Manage an Application Mutex for the current application\r\n'' @remarks  Mutex name = APP_MUTEX\r\n'' @author   Christoph Juengling &lt;christoph@juengling-edv.de&gt;\r\n'' @link   https:\/\/gitlab.com\/juengling\/vb-and-vba-code-library\r\n<span style=\"color:blue;\">Option Explicit<\/span>\r\n#If VBA7 Then\r\n<span style=\"color:blue;\">Private <\/span>Declare PtrSafe Function CreateMutex Lib \"kernel32\" Alias \"CreateMutexA\" (lpMutexAttributes<span style=\"color:blue;\"> As <\/span>Any, _\r\n      ByVal bInitialOwner<span style=\"color:blue;\"> As Long<\/span>, ByVal lpName<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Long<\/span>Ptr\r\n<span style=\"color:blue;\">Private <\/span>Declare PtrSafe Function CloseHandle Lib \"kernel32\" (ByVal hObject<span style=\"color:blue;\"> As Long<\/span>Ptr)<span style=\"color:blue;\"> As Long<\/span>\r\n<span style=\"color:blue;\">Private <\/span>Declare PtrSafe Function ReleaseMutex Lib \"kernel32\" (ByVal hMutex<span style=\"color:blue;\"> As Long<\/span>Ptr)<span style=\"color:blue;\"> As Long<\/span>\r\n#Else\r\n<span style=\"color:blue;\">Private <\/span>Declare Function CreateMutex Lib \"kernel32\" Alias \"CreateMutexA\" (lpMutexAttributes<span style=\"color:blue;\"> As <\/span>Any, _\r\n     ByVal bInitialOwner<span style=\"color:blue;\"> As Long<\/span>, ByVal lpName<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Long<\/span>\r\n<span style=\"color:blue;\">Private <\/span>Declare Function CloseHandle Lib \"kernel32\" (ByVal hObject<span style=\"color:blue;\"> As Long<\/span>)<span style=\"color:blue;\"> As Long<\/span>\r\n<span style=\"color:blue;\">Private <\/span>Declare Function ReleaseMutex Lib \"kernel32\" (ByVal hMutex<span style=\"color:blue;\"> As Long<\/span>)<span style=\"color:blue;\"> As Long<\/span>\r\n#End If\r\n<span style=\"color:blue;\">Private <\/span>m_lMutexHandle<span style=\"color:blue;\"> As Long<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>Class_Initialize()\r\n     m_lMutexHandle = 0\r\n     CreateMyMutex\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>Class_Terminate()\r\n     ReleaseMyMutex\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n'' CreateMutex the Mutex\r\n<span style=\"color:blue;\">Public Sub <\/span>CreateMyMutex()\r\n     m_lMutexHandle = CreateMutex(ByVal CLng(0), CLng(1), APP_MUTEX)\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n''''\r\n'' ReleaseMutex the Mutex and close handle\r\n''\r\n<span style=\"color:blue;\">Public Sub <\/span>ReleaseMyMutex()\r\n     <span style=\"color:blue;\">If <\/span>m_lMutexHandle &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n         ReleaseMutex m_lMutexHandle\r\n         CloseHandle m_lMutexHandle\r\n         m_lMutexHandle = 0\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Klasse zum Nutzen eines Mutex<\/span><\/b><\/p>\n<p>Die Erzeugung passiert in <b>Class_Initialize<\/b>, die Zerst&ouml;rung in <b>Class_Terminate<\/b>. Der einzige Bezug in unsere Applikation ist hier die Nutzung der globalen Konstanten <b>APP_MUTEX<\/b>. Diese deklariert den Namen des Mutex:<\/p>\n<pre><span style=\"color:blue;\">Public <\/span>Const APP_MUTEX = \"Mein Name ist Hase\"<\/pre>\n<p>Die Bezeichnung sollte sinnvollerweise dem Namen der Applikation entsprechen, so dass man nat&uuml;rlich auch <b>APP_NAME <\/b>verwenden kann.<\/p>\n<p>Wichtig ist die Einzigartigkeit im Hinblick auf andere Applikationen! Eine solche Deklaration muss nat&uuml;rlich namensgleich sp&auml;ter auch im InnoSetup-Skript enthalten sein, damit Setup und Applikation &uuml;ber dieselbe Bezeichnung verf&uuml;gen.<\/p>\n<p>Nun m&uuml;ssen wir nur noch daf&uuml;r sorgen, dass<\/p>\n<ul>\n<li>eine Modul-Variable f&uuml;r die Instanz der Klasse existiert,<\/li>\n<li>diese beim Start instanziiert wird und<\/li>\n<li>vor dem Beenden der Applikation zerst&ouml;rt wird.<\/li>\n<\/ul>\n<p>Das ist ebenfalls trivial. In einem Modul, in dem vielleicht noch weitere globale Deklarationen stehen, f&uuml;gen wir diese Zeile ein:<\/p>\n<pre><span style=\"color:blue;\">Public <\/span>mutex<span style=\"color:blue;\"> As <\/span>clsMutex<\/pre>\n<p>In dem Code f&uuml;r die Initialisierung:<\/p>\n<pre><span style=\"color:blue;\">Set<\/span> mutex = <span style=\"color:blue;\">New<\/span> clsMutex<\/pre>\n<p>Und f&uuml;r das Beenden:<\/p>\n<pre><span style=\"color:blue;\">Set<\/span> mutex = Nothing<\/pre>\n<p>Das war doch einfach, oder Streng genommen ist die letzte Aktion nicht n&ouml;tig, da der Mutex mit dem Beenden der Applikation automatisch gel&ouml;scht wird.<\/p>\n<h2>Den Mutex in InnoSetup eintragen<\/h2>\n<p>In InnoSetup ist die Sache sogar noch einfacher, denn der ganze Mechanismus zum &Uuml;berpr&uuml;fen und Reagieren ist dort bereits enthalten, Code m&uuml;ssen wir daf&uuml;r nicht schreiben.<\/p>\n<p>Wir m&uuml;ssen nur daf&uuml;r sorgen, dass InnoSetup den Namen des Mutex erf&auml;hrt. Wie schon erw&auml;hnt, muss diese Deklaration nat&uuml;rlich identisch mit der Konstanten aus unserer Applikation sein, und das betrifft auch die Gro&szlig;-\/Kleinschreibung!<\/p>\n<p><!--30percent--><\/p>\n<p>Im Deklarationsbereich zu Beginn des Skriptes schreiben wir also:<\/p>\n<pre>#define MyAppMutex \"Mein Name ist Hase\" <\/pre>\n<p>Und in der Gruppe <b>[Setup]<\/b>:<\/p>\n<pre>AppMutex={#MyAppMutex}<\/pre>\n<p>Mehr ist nicht n&ouml;tig. Und wie funktioniert das nun<\/p>\n<p>Zum einen genau wie oben beschrieben. Wenn das Setup bei der Ausf&uuml;hrung entdeckt, dass der Mutex bereits existiert, zeigt es die Meldung aus Bild 1 an.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_01\/mutex-meldung.png\" alt=\"Mutex-Meldung\" width=\"499,5589\" height=\"243,0286\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Mutex-Meldung<\/span><\/b><\/p>\n<p>Nun kann der Anwender entsprechend darauf reagieren. Besonders elegant arbeitet InnoSetup jedoch, wenn es f&uuml;r die Installation mit dem Kommandozeilen-Argument <b>silent <\/b>aufgerufen wurde.<\/p>\n<p>Dann n&auml;mlich verzichtet es auf alle R&uuml;ckfragen mit Benutzerinteraktion. F&uuml;r den Mutex-Fall bedeutet das, dass das Setup solange abwartet, bis der Mutex verschwunden ist. Dann wird das Setup mit Standardeinstellungen fortgef&uuml;hrt.<\/p>\n<p>Dieser Mechanismus hat den besonderen Reiz, dass die Applikation selbst per <b>Shell<\/b>-Execute die Ausf&uuml;hrung des Setups anstarten und sich dann in aller Ruhe beenden kann. Erst wenn der Mutex gel&ouml;scht ist, l&auml;uft das Setup durch.<\/p>\n<h2>Beta oder Final<\/h2>\n<p>Nicht immer ist ein Programm sofort fertig, auch wenn der Entwickler noch so &uuml;berzeugt von seiner Arbeit ist. Daher kann es sinnvoll sein, ausgew&auml;hlte User in einen Beta-Test einzubeziehen.<\/p>\n<p>Dabei sollte jedoch immer auf eine strenge Trennung nicht nur der Programminstallation, sondern auch bez&uuml;glich der Daten geachtet werden. Eine M&ouml;glichkeit dabei ist eine Kombination aus dem Setup-Skript und dem Code, der f&uuml;r die Tabelleneinbindung sorgt. Worauf m&uuml;ssen wir achten, und wie machen wir uns die Arbeit m&ouml;glichst einfach<\/p>\n<p>Beginnen wir mit der Frage, bez&uuml;glich welcher Einstellungen sich Beta- und Final-Version unterscheiden:<\/p>\n<ul>\n<li>Installationspfad<\/li>\n<li>Beta-Hinweis oder Lizenzvereinbarung<\/li>\n<li>Pfad zum Backend<\/li>\n<\/ul>\n<h2>Installationspfad<\/h2>\n<p>Nehmen wir (wie schon im ersten Teil dargelegt) an, dass wir unser &#8222;normales&#8220; Programm unter <b>C:\\Users\\USERNAME\\AppData\\Local\\Programs <\/b>installieren wollen. Dort wird sicherlich f&uuml;r jedes Programm ein eigenes Unterverzeichnis verwendet werden.<\/p>\n<p>Es bietet sich also an, dies f&uuml;r unser eigenes Programm ebenfalls zu tun, und zwar getrennt f&uuml;r Beta- und Final-Version.<\/p>\n<p>Dazu m&uuml;ssen wir also die Setup-Einstellung <b>DefaultDirName <\/b>angemessen ver&auml;ndern. Bisher steht dort <b>{userpf}\\{#MyAppName}<\/b>. Es spricht also nichts dagegen, zum Beispiel <b>{userpf}\\{#MyAppName}<\/b>-Beta zu verwenden.<\/p>\n<p>Doch mir widerstrebt es, jedesmal mitten im Skript eine &Auml;nderung vorzunehmen. Da kann man sich leicht vertun, und es wird auch nicht die einzige &Auml;nderung bleiben. Eine L&ouml;sung f&uuml;r diesen Fall sind wieder einmal die Konstanten, die wir ja bereits kennengelernt haben. Ich f&uuml;ge also zun&auml;chst eine weitere hinzu:<\/p>\n<pre>#define MyAppStatus \"Beta\"<\/pre>\n<p>oder<\/p>\n<pre>#define MyAppStatus \"Final\"<\/pre>\n<p>Damit haben wir wieder eine Einstellung, die wir nur am Anfang des Skriptes ver&auml;ndern m&uuml;ssen, wodurch hoffentlich alle anderen Settings entsprechend angepasst werden.<\/p>\n<p>Damit das funktioniert, nutzen wir eine weitere M&ouml;glichkeit von InnoSetup, die uns als Entwickler nat&uuml;rlich vertraut ist: Die <b>If-Then-Else<\/b>-Anweisung. Sie funktioniert im Prinzip wie von VBA her bekannt, nur sieht die Syntax ein wenig anders aus.<\/p>\n<p>Im folgenden Beispiel erweitere ich bei einer Betaversion den Standard-Installationspfad und die Startmen&uuml;-Gruppe zum Beispiel durch den Zusatz <b>-Beta<\/b>:<\/p>\n<pre>#if MyAppStatus == \"Beta\"\r\nDefaultDirName={userpf}\\{#MyAppName}-{#MyAppStatus}\r\nDefaultGroupName={#MyAppName}-{#MyAppStatus}\r\n#else\r\nDefaultDirName={userpf}\\{#MyAppName}\r\nDefaultGroupName={#MyAppName}\r\n#endif<\/pre>\n<p>Selbstverst&auml;ndlich sollten wir auch den Registry-Eintrag f&uuml;r die Installation entsprechend ver&auml;ndern. Daf&uuml;r ist bekanntlich die Einstellung <b>AppId <\/b>zust&auml;ndig.<\/p>\n<p>Also schreiben wir analog zum obigen:<\/p>\n<pre>#if MyAppStatus == \"Beta\"\r\nAppId={#MyAppName}-{#MyAppStatus}\r\n#else\r\nAppId={#MyAppName}\r\n#endif<\/pre>\n<p>Nat&uuml;rlich d&uuml;rfen wir diese beiden auch zusammenf&uuml;gen, denn die Reihenfolge der Settings in der Gruppe <b>[Setup] <\/b>ist nicht von Bedeutung.<\/p>\n<h2>Betahinweis oder Lizenzvereinbarung<\/h2>\n<p>Genau so verfahren wir bei der Entscheidung &#8222;Beta-Hinweis oder Lizenzvereinbarung&#8220;. F&uuml;r die Anzeige dieses Zusatztextes ist bekanntlich die <b>[Languages]<\/b>-Gruppe verantwortlich. Dort steht bisher:<\/p>\n<pre>[Languages]\r\nName: \"EN\"; MessagesFile: \"compiler:Default.isl\"; LicenseFile: \"license-en.txt\"\r\nName: \"DE\"; MessagesFile: \"compiler:Languages\\German.isl\"; LicenseFile: \"license-de.rtf\"<\/pre>\n<p>Nun erg&auml;nzen wir das <b>If-Else-Endif <\/b>und &auml;ndern <b>LicenseFile <\/b>einfach in <b>InfoBeforeFile<\/b>:<\/p>\n<pre>[Languages]\r\n#if MyAppStatus == \"Beta\"\r\nName: \"EN\"; MessagesFile: \"compiler:Default.isl\"; InfoBeforeFile: \"beta-en.rtf\"\r\nName: \"DE\"; MessagesFile: \"compiler:Languages\\German.isl\"; InfoBeforeFile: \"beta-de.rtf\"\r\n#else\r\nName: \"EN\"; MessagesFile: \"compiler:Default.isl\"; LicenseFile: \"license-en.rtf\"\r\nName: \"DE\"; MessagesFile: \"compiler:Languages\\German.isl\"; LicenseFile: \"license-de.rtf\"\r\n#endif<\/pre>\n<h2>Spezielles Backend f&uuml;r die Betaversion<\/h2>\n<p>Nun bleibt noch der dritte Teil unserer Aufgabenstellung, die Anbindung des richtigen Backends.<\/p>\n<p>Ich gehe dabei von folgender &Uuml;berlegung aus: Ein &#8222;produktives&#8220; Backend sollte immer im Netzwerk liegen, da schlie&szlig;lich mehrere User auf die gleichen Daten zugreifen m&uuml;ssen.<\/p>\n<p>Ein Backend f&uuml;r den Betatest wiederum ist ausgesprochen individuell und vor allem auch &#8222;fl&uuml;chtig&#8220;, da hier nicht nur bewusst gespielt wird, sondern auch mit Problemen zu rechnen ist. Daher rechne ich damit, dass ich das Beta-Backend des &Ouml;fteren neu installiere.<\/p>\n<p>Ich entscheide also, dass f&uuml;r unseren Betatest das Backend im selben Verzeichnis wie das Beta-Frontend liegen soll, w&auml;hrend das &#8222;normale&#8220; Backend weiterhin im Netz liegt. Die Installation des Beta-Backends erledigen wir durch einen zus&auml;tzlichen Eintrag in der <b>[Files]<\/b>-Rubrik:<\/p>\n<pre>#if MyAppStatus == \"Beta\"\r\n; Backend nur w&auml;hrend der Testphase installieren\r\nSource: \"MyBetaBackend.accdb\"; DestDir: \"{app}\"; Flags: ignoreversion\r\n#endif<\/pre>\n<p>Bitte beachten Sie, dass wir als Zielpfad der Installation des Backends einfach nur <b>{app} <\/b>angeben m&uuml;ssen. Die Unterscheidung f&uuml;r den speziellen Pfad f&uuml;r die Betaversion haben wir ja bereits durch <b>DefaultDirName <\/b>getroffen!<\/p>\n<p>F&uuml;r den Backend-Pfad ben&ouml;tigen wir noch einen kleinen Umweg, da wir mit InnoSetup nicht direkt auf die eingebundenen Tabellen einer Access-Datenbank zugreifen k&ouml;nnen.<\/p>\n<p>Wir schreiben also einfach den Pfad zum Backend in eine <b>INI<\/b>-Datei oder die Registry. Die Applikation wiederum muss dann beim Start diese Information von dort auslesen und mit dieser die Tabellen von dem richtigen Backend einbinden. Nehmen wir nun also eine <b>INI<\/b>-Datei, f&uuml;r die Registry haben wir ja bereits <b>[Registry] <\/b>kennengelernt.<\/p>\n<p>Der Zugriff auf eine <b>INI<\/b>-Datei geht &uuml;ber die Rubrik <b>[INI]<\/b>. Ich lege fest, dass unsere <b>INI<\/b>-Datei folgende Informationen beinhalten soll:<\/p>\n<pre>[Backend]\r\nPath=\r\nFilename=<\/pre>\n<p>Ich habe <b>Path<\/b> und <b>Filename <\/b>hier getrennt erfasst, da es uns so leichter f&auml;llt, diese aus dem Setup heraus zu setzen. Zusammenbauen ist schlie&szlig;lich immer einfacher als auftrennen.<\/p>\n<p>Und so sieht das dann in InnoSetup aus:<\/p>\n<pre>[INI]\r\n#if MyAppStatus == \"Beta\"\r\nFilename: \"{app}\\Testapplikation.ini\"; Section: \"Backend\"; Key: \"Path\"; String: \"{app}\"\r\nFilename: \"{app}\\Testapplikation.ini\"; Section: \"Backend\"; Key: \"Filename\"; String: \"Beta-backend.accdb\"\r\n#else\r\nFilename: \"{app}\\Testapplikation.ini\"; Section: \"Backend\"; Key: \"Path\"; String: \"N:\\irgendwo\"; Flags: createkeyifdoesntexist\r\nFilename: \"{app}\\Testapplikation.ini\"; Section: \"Backend\"; Key: \"Filename\"; String: \"Testapplikation-backend.accdb\"; Flags: createkeyifdoesntexist\r\n#endif<\/pre>\n<p>Das Flag <b>createkeyifdoesntexist <\/b>habe ich bei der finalen Version (alles, was nicht &#8222;Beta&#8220; hei&szlig;t, wird als final betrachtet) hinzugef&uuml;gt, damit der <b>INI<\/b>-Eintrag notfalls vom User oder dem Admin ge&auml;ndert werden kann.<\/p>\n<p>Manchmal ver&auml;ndert sich ja etwas im Netzwerk und wir haben vielleicht nicht die Zeit oder daran gedacht, dies auch im Setup anzupassen. Wenn der Eintrag <b>Path<\/b> oder <b>Filename<\/b> also bereits existiert, dann wird das finale Setup daran nichts mehr &auml;ndern.<\/p>\n<p>Die &Auml;nderbarkeit durch den User ist auch der Grund, weshalb ich f&uuml;r diese Einstellung lieber eine <b>INI<\/b>-Datei als einen Registry-Eintrag verwende.<\/p>\n<p>Denn ich habe es schon erlebt, dass die User zwar technisch (also indirekt durch die Applikation) in <b>HKEY_CURRENT_USER <\/b>lesen und schreiben konnten, ihnen aber der Aufruf von RegEdit per Policy verwehrt wurde.<\/p>\n<h2>Digitale Signatur des Setups<\/h2>\n<p>Wenn ich eine <b>EXE<\/b>-Datei von irgendwoher herunterlade, muss ich dem Herausgeber vertrauen. Das betrifft viele Dinge: Virenfreiheit, Funktionsf&auml;higkeit und vielleicht auch die Tatsache, dass das Programm nichts anderes macht, als versprochen (Stichwort &#8222;Trojaner&#8220;).<\/p>\n<p>Aber auch wenn ich dem genannten Autor durchaus vertraue, woher wei&szlig; ich eigentlich, dass es sich bei dem &#8222;Herausgeber&#8220; auch wirklich um den Christoph J&uuml;ngling handelt, den ich kenne, und nicht eine ganz andere Person, die sich nur so nennt<\/p>\n<p>Um dies sicherzustellen, k&ouml;nnen wir eine digitale Signatur verwenden. Das ist im Grunde eine kryptographische Unterschrift f&uuml;r unsere <b>EXE<\/b>-Datei. Wie ich in diesem Artikel bereits beschrieben habe, k&ouml;nnen wir unsere Access-Datenbank leider nicht auf diese Weise signieren.<\/p>\n<p>Was Microsoft in den anderen Office-Programmen als VBA-Signatur eingebaut hat, funktioniert in Access leider nicht.<\/p>\n<p>Wir k&ouml;nnen aber unser Setup signieren, so dass der Anwender vor der Installation pr&uuml;fen kann, ob diese EXE-Datei auch wirklich von uns ist.<\/p>\n<p>Folgendes ist dazu notwendig:<\/p>\n<ul>\n<li>Zertifikat beschaffen<\/li>\n<li>Zertifikat in Windows installieren<\/li>\n<li><b>signtool.exe <\/b>herunterladen und installieren<\/li>\n<li><b>Sign Tools <\/b>in InnoSetup und\/oder InnoSetup Script Studio konfigurieren<\/li>\n<li>Signierungswunsch in das InnoSetup-Skript eintragen<\/li>\n<\/ul>\n<p>Die ersten vier Schritte sind nur einmal als Vorbereitung erforderlich. F&uuml;r weitere Setups muss dort nur der letzte ausgef&uuml;hrt werden.<\/p>\n<h2>Zertifikat beschaffen und installieren<\/h2>\n<p>Das digitale Signieren ist in InnoSetup verh&auml;ltnism&auml;&szlig;ig einfach. Voraussetzung ist jedoch, dass wir ein Zertifikat besitzen und in Windows installiert haben.<\/p>\n<p>Dieses befindet sich (hoffentlich) in dem Speicher &#8222;Eigene Zertifikate&#8220;. Starten Sie die Anwendung &#8222;Benutzerzertifikate verwalten&#8220; aus dem Startmen&uuml; und navigieren Sie zu dem Bereich, den Sie im Screenshot aus Bild 2 vorfinden.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_01\/cert-manager.png\" alt=\"Zertifikats-Manager\" width=\"700\" height=\"146,9353\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Zertifikats-Manager<\/span><\/b><\/p>\n<p>Der gezeigte Anbieter <b>Sectigo <\/b>(ehemals <b>Comodo<\/b>) ist nur einer von mehreren. Wichtig ist, dass das Zertifikat f&uuml;r das &#8222;Code-Signing&#8220; tauglich ist.<\/p>\n<p>Am besten ist es, wenn man sich f&uuml;r diese Schritte nach den Anleitungen des Zertifikatsanbieters richtet. Dabei wird die Identit&auml;t des Antragstellers gepr&uuml;ft.<\/p>\n<p>In einem Fall vor mehreren Jahren war nur die Mitteilung meiner DUNS-Nummer erforderlich, bei der nachfolgenden erneuten Beantragung musste ich ein Selfie mit Personalausweis einsenden.<\/p>\n<h2>Signtool herunterladen und installieren<\/h2>\n<p>Die Datei <b>signtool.exe <\/b>f&uuml;hrt die Signierung tats&auml;chlich durch. Es l&auml;sst sich offenbar nur als Bestandteil des Windows SDK herunterladen. Dieses wiederum ben&ouml;tigt das Dotnet Framework 4.<\/p>\n<p>So kriegt man die Festplatte auch voll. Allerdings ben&ouml;tigt man nicht das gesamte SDK.<\/p>\n<p>In einem aktuellen Download reichte es, nur die Installation der <b>Windows SDK Signing Tools for Desktop Apps<\/b> anzuklicken, was letztlich dann nur 3,9 MB Platz auf der Platte ben&ouml;tigte.<\/p>\n<h2>Sign Tools konfigurieren<\/h2>\n<p>F&uuml;r InnoSetup und\/oder InnoSetup Script Studio m&uuml;ssen wir jeweils einmalig das Signtool konfigurieren. Dies erfolgt im Men&uuml; <b>Tools|Configure Sign Tools<\/b>.<\/p>\n<p>Dabei wird unter einem beliebigen symbolischen Namen der Kommandozeilenbefehl festgelegt, mit dem <b>signtool.exe <\/b>ausgef&uuml;hrt wird. Diese umfasst mindestens folgendes:<\/p>\n<pre>signtool.exe sign DATEINAME<\/pre>\n<p>Da der Dateiname nat&uuml;rlich immer vom konkreten Setup-Skript festgelegt wird, verwenden wir f&uuml;r diesen den Platzhalter <b>$f<\/b>. Mittels <b>\/a <\/b>sorgen wir f&uuml;r die automatische Ermittlung des passenden Zertifikates, und <b>\/f <\/b>definiert einen Timeserver. Dieser erm&ouml;glicht es dem User, die <b>EXE<\/b>-Datei auch dann noch auszuf&uuml;hren, wenn das Zertifikat l&auml;ngst abgelaufen ist. Der Timeserver best&auml;tigt dabei n&auml;mlich, dass es zum Zeitpunkt der Signierung g&uuml;ltig war. Andernfalls w&auml;re die Applikation nur solange installierbar, wie der Schl&uuml;ssel g&uuml;ltig ist.<\/p>\n<pre>signtool sign \/a \/t http:\/\/timestamp.comodoca.com $f<\/pre>\n<h2>Eintrag in InnoSetup<\/h2>\n<p>Nach diesen ganzen Vorbereitungen ist im Setup-Skript nicht mehr viel zu tun. F&uuml;gen Sie in der Rubrik <b>[Setup] <\/b>diese beiden Zeilen ein:<\/p>\n<pre>SignTool=cjsign\r\nSignedUninstaller=<span style=\"color:blue;\">True<\/span><\/pre>\n<h2>Ergebnis unter Windows 10<\/h2>\n<p>Unter Windows 10 sieht das dann zum Beispiel f&uuml;r ein unsigniertes Setup wie in Bild 3 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_01\/OhneSignatur.png\" alt=\"Ohne Signatur\" width=\"499,5589\" height=\"325,6148\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Ohne Signatur<\/span><\/b><\/p>\n<p>Das signierte Setup erscheint wie in Bild 4.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_01\/MitSignatur.png\" alt=\"Mit Signatur\" width=\"499,5589\" height=\"304,8156\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Mit Signatur<\/span><\/b><\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>beta-de.rtf<\/p>\n<p>beta-en.rtf<\/p>\n<p>license-de.rtf<\/p>\n<p>license-en.rtf<\/p>\n<p>readme.txt<\/p>\n<p>setup.iss<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/35600969-6EDF-4C20-9977-BC6CA01E7CC7\/aiu_1355.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In diesem Teil widmen wir uns einigen Restarbeiten f&uuml;r das Erstellen eines Setups f&uuml;r Access-Applikationen. Diese Arbeiten sind zwar keineswegs unbedingt notwendig, runden aber unser Setup ab und sorgen daher beim Anwender oder Administrator f&uuml;r ein &#8222;gutes Gef&uuml;hl&#8220;. Wir wollen zun&auml;chst sicherstellen, dass unsere Applikation nicht l&auml;uft, wenn wir sie updaten wollen. Dann unterscheiden wir bei der Installation zwischen Beta- und finaler Version. Und letztlich wollen wir unser Setup dann noch digital signieren.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[66012022,662022,44000039],"tags":[],"class_list":["post-55001355","post","type-post","status-publish","format-standard","hentry","category-66012022","category-662022","category-Setup_und_Weitergabe"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Setup f&uuml;r Access-Applikationen, Restarbeiten - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Setup f&uuml;r Access-Applikationen, Restarbeiten\" \/>\n<meta property=\"og:description\" content=\"In diesem Teil widmen wir uns einigen Restarbeiten f&uuml;r das Erstellen eines Setups f&uuml;r Access-Applikationen. Diese Arbeiten sind zwar keineswegs unbedingt notwendig, runden aber unser Setup ab und sorgen daher beim Anwender oder Administrator f&uuml;r ein &quot;gutes Gef&uuml;hl&quot;. Wir wollen zun&auml;chst sicherstellen, dass unsere Applikation nicht l&auml;uft, wenn wir sie updaten wollen. Dann unterscheiden wir bei der Installation zwischen Beta- und finaler Version. Und letztlich wollen wir unser Setup dann noch digital signieren.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2022-01-31T15:18:42+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg08.met.vgwort.de\/na\/dd4fc42fb3ac4e8c9da48daa394d3dc6\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"15\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Setup_fuer_AccessApplikationen_Restarbeiten\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Setup_fuer_AccessApplikationen_Restarbeiten\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Setup f&uuml;r Access-Applikationen, Restarbeiten\",\"datePublished\":\"2022-01-31T15:18:42+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Setup_fuer_AccessApplikationen_Restarbeiten\\\/\"},\"wordCount\":2514,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Setup_fuer_AccessApplikationen_Restarbeiten\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg08.met.vgwort.de\\\/na\\\/dd4fc42fb3ac4e8c9da48daa394d3dc6\",\"articleSection\":[\"1\\\/2022\",\"2022\",\"Setup und Weitergabe\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Setup_fuer_AccessApplikationen_Restarbeiten\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Setup_fuer_AccessApplikationen_Restarbeiten\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Setup_fuer_AccessApplikationen_Restarbeiten\\\/\",\"name\":\"Setup f&uuml;r Access-Applikationen, Restarbeiten - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Setup_fuer_AccessApplikationen_Restarbeiten\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Setup_fuer_AccessApplikationen_Restarbeiten\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg08.met.vgwort.de\\\/na\\\/dd4fc42fb3ac4e8c9da48daa394d3dc6\",\"datePublished\":\"2022-01-31T15:18:42+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Setup_fuer_AccessApplikationen_Restarbeiten\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Setup_fuer_AccessApplikationen_Restarbeiten\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Setup_fuer_AccessApplikationen_Restarbeiten\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg08.met.vgwort.de\\\/na\\\/dd4fc42fb3ac4e8c9da48daa394d3dc6\",\"contentUrl\":\"http:\\\/\\\/vg08.met.vgwort.de\\\/na\\\/dd4fc42fb3ac4e8c9da48daa394d3dc6\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Setup_fuer_AccessApplikationen_Restarbeiten\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Setup f&uuml;r Access-Applikationen, Restarbeiten\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Setup f&uuml;r Access-Applikationen, Restarbeiten - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/","og_locale":"de_DE","og_type":"article","og_title":"Setup f&uuml;r Access-Applikationen, Restarbeiten","og_description":"In diesem Teil widmen wir uns einigen Restarbeiten f&uuml;r das Erstellen eines Setups f&uuml;r Access-Applikationen. Diese Arbeiten sind zwar keineswegs unbedingt notwendig, runden aber unser Setup ab und sorgen daher beim Anwender oder Administrator f&uuml;r ein \"gutes Gef&uuml;hl\". Wir wollen zun&auml;chst sicherstellen, dass unsere Applikation nicht l&auml;uft, wenn wir sie updaten wollen. Dann unterscheiden wir bei der Installation zwischen Beta- und finaler Version. Und letztlich wollen wir unser Setup dann noch digital signieren.","og_url":"https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/","og_site_name":"Access im Unternehmen","article_published_time":"2022-01-31T15:18:42+00:00","og_image":[{"url":"http:\/\/vg08.met.vgwort.de\/na\/dd4fc42fb3ac4e8c9da48daa394d3dc6","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"15\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Setup f&uuml;r Access-Applikationen, Restarbeiten","datePublished":"2022-01-31T15:18:42+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/"},"wordCount":2514,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/#primaryimage"},"thumbnailUrl":"http:\/\/vg08.met.vgwort.de\/na\/dd4fc42fb3ac4e8c9da48daa394d3dc6","articleSection":["1\/2022","2022","Setup und Weitergabe"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/","url":"https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/","name":"Setup f&uuml;r Access-Applikationen, Restarbeiten - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/#primaryimage"},"thumbnailUrl":"http:\/\/vg08.met.vgwort.de\/na\/dd4fc42fb3ac4e8c9da48daa394d3dc6","datePublished":"2022-01-31T15:18:42+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/#primaryimage","url":"http:\/\/vg08.met.vgwort.de\/na\/dd4fc42fb3ac4e8c9da48daa394d3dc6","contentUrl":"http:\/\/vg08.met.vgwort.de\/na\/dd4fc42fb3ac4e8c9da48daa394d3dc6"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Setup_fuer_AccessApplikationen_Restarbeiten\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Setup f&uuml;r Access-Applikationen, Restarbeiten"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001355","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55001355"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001355\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001355"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001355"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001355"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}