PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Inno Setup - Installationspfad aus Registrierung beziehen



Grand
17.11.2014, 12:19
Hallo zusammen,

bin zurzeit dabei mit Inno Setup ein Installer zu erzeugen, der den Installationspfad automatisch erkennt.

Das funktiomiert auch schon fast, nur komm ich jetzt nicht mehr weiter. Bei der Installation erkennt er jetzt folgenden Pfad (E:\Game\World of Tanks\Uninstall.exe)


DefaultDirName={code:etRegistryPath}





function GetRegistryPath(DefaultPath: string): string;

begin
if not RegQueryStringValue(HKLM, 'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\World of Tanks', 'UninstallString', Result) then Result := ExpandConstant (DefaultPath);
end;



Nur soll jetzt nur folgender Pfad da stehen (E:\Game\World of Tanks) also Uninstall.exe soll nicht mit da stehen.

Kann mir da vielleicht jemand weiter helfen.

MfG

jabu
17.11.2014, 23:14
Ich kenne mich nicht mit Inno Setup aus und kann dir leider keine fertige Lösung vorlegen. Pascal gehört auch nicht zu meinen bevorzugten Sprachen. Trotzdem ist offensichtlich, dass du mit der Code-Zeile versuchst, den Deinstallationseintrag auszulesen, weshalb das von dir angeführte Ergebnis erwartungsgemäß ist.

Jetzt könntest du von dem String alles hinter dem letzten Backslash kürzen. Eine kurze Recherche hat mich zu der zugehörigen Doku geführt und dort zu der Funktion ExtractFilePath (http://www.jrsoftware.org/ishelp/topic_isxfunc_extractfilepath.htm).

Damit müsstest du das benötigte Zurechtstutzen auf den reinen Pfad bewerkstelligen können. Es gibt aber noch eine andere Möglichkeit, indem du anstelle des Deinstallationseintrags ("UninstallString") den Installationsort ("InstallLocation") ausliest. Falls das gewünscht ist, müsste deine Codezeile entsprechend angepasst werden.

Allerdings existiert nicht immer ein solcher Eintrag, oder er existiert, ist aber leer, weshalb ich auf die Möglichkeit, den "UninstallString" auszuwerten, nicht verzichten würde. Im Zweifel kannst du beides auslesen.

Dann würde ich noch mindestens prüfen, ob der Pfad, in den du hineininstallieren willst, überhaupt existiert. Aber bevor irgendwas automatisch losrattert, solltest du immer den Benutzer fragen, sodass er wenigstens vorher den Pfad einsehen kann und eine Möglichkeit zum Abändern oder Abbrechen hat.

Grand
18.11.2014, 12:33
Danke für deine Antwort.

Über ("InstallLocation") geht das leider nicht weil es dafür kein eintrag in der Regedit gibt.

So wie ich mir gedacht hab, das es funktioniert, gehts leider nicht.

Kannst du mir das anhand eines bsp. erklären bitte?

MfG

jabu
19.11.2014, 18:47
Bitte noch etwas gedulden, da kommt noch was! ;)

Grand
19.11.2014, 19:02
Ich muss mich entschuldigen, ich habe die ganze Zeit den falschen Regediteintrag benutzt, da war noch was Installiert was nicht zu World of Tanks gehört hat.

Jetzt hab ich nur noch folgendes zur auswahl:



Windows Registry Editor Version 5.00

[HKEY_USERS\S-1-5-21-2783449451-2498162217-1225686517-1000\Software\Microsoft\Windows\CurrentVersion\Uninstall\{1EAC1D02-C6AC-4FA6-9A44-96258C37C812EU}_is1]
"DisplayName"="World of Tanks"
"DisplayIcon"="E:\\Game\\World_of_Tanks\\WoTLauncher.exe"
"UninstallString"="\"E:\\Game\\World_of_Tanks\\unins000.exe\""
"QuietUninstallString"="\"E:\\Game\\World_of_Tanks\\unins000.exe\" /SILENT"
"Publisher"="Wargaming.net"
"URLInfoAbout"="http://wargaming.net"
"HelpLink"="https://support.worldoftanks.eu/"
"NoModify"=dword:00000001
"NoRepair"=dword:00000001
"InstallDate"="20141119"
"EstimatedSize"=dword:00005c24


mehr kann ich in der Regestrierung nicht finden.

jabu
19.11.2014, 21:36
Du müsstest in der Registry unter HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node nachgucken, ob dort ein Eintrag für "World of Tanks" vorhanden ist. Oft verstecken sich die Einträge unter Publishernamen.

Übrigens wirst du mit diesen Wow6432Node-Zweigen ins Leere laufen, wenn das Programm unter einem 32-Bit-Windows läuft, weil es sie dort nicht gibt (es sei denn, jemand legt welche an, aber davon weiß Windows nichts)!
Ein 64-Bit-Windows sorgt jedoch selbst dafür, dass bei der Ausführung von 32-Bit-Programmen automatisch in die Wow6432Node-Zweige umgeleitet wird, sowohl beim Lesen als auch beim Schreiben. Verwendest du also einen 32-Bit-Installer, landest du automatisch dort. Das klappt auch hier. Also ist es aus Kompatibilitätsgründen angesagt, das 'Wow6432Node' jeweils wegzulassen. Das habe ich mit InnoSetup getestet, und es funktioniert.

Jeder kocht seine eigene Suppe, z.B.

Path
InstDir
Install_Dir
INSTALL_DIR
...

Das nervt ganz schön. Man muss schon ungefähr wissen, wonach man sucht. Manche Programme aktualisieren sogar diesen Pfad, wenn man sie verschiebt und dann ausführt, aber eben nur manche. Einen Königsweg gibt es nicht.

Aber mal grundsätzlich zu den Uninstall-Einträgen, das mit InnoSetup und diesem reichlich abgespeckten Pascal-Derivat auszulesen, ist nicht das größte Problem, sondern die überflüssigen Parameter abzustreifen, da es kein eindeutiges Anzeichen dafür gibt, wo ein Pfad aufhört und wo die Parameter anfangen. Bei dem "QuietUninstallString" siehst du, was ich mit "Parametern" meine. Mal gibt es welche, mal nicht, und diese Ordnung mit den Anführungszeichen ist nicht selbstverständlich. Sie fehlen oft ganz. Und wenn dann mehrfach '.exe' vorkommt, weißt du nicht, ob das ein Bestandteil des Pfades, des Dateinamens oder des Parameters ist. Manche Installer sind zentral installiert, z.B. der Microsoft-Installer oder InstallShield. Dort lässt sich aus dem 'UninstallString' meistens nichts direkt herauslesen.

Für die Extraktion des Pfades gibt es nicht die eine Lösung, weil man sonst das gesamte Verhalten von Windows bei der Befehlsauführung nachahmen müsste, samt Abstieg in den physisch vorhandenen Pfad. Nur so kann man ganz sicher sein, den Pfad richtig zu interpretieren. Aber ich habe etwas Code erstellt, was dir einen ersten Ansatz liefern kann, kommt später. In dem aufgeführten Fall aus deiner Registry ist es natürlich trivial, solange sich nichts ändert. Aber sicher wissen kann man das nicht.

Grand
20.11.2014, 10:14
unter HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node ist leider nichts zu finden, das wäre ja auch zu einfach:D

Achso was mir aufgefallen ist, bei andere Mod packs, wo das vorher ging das er den Pfad automatisch gefunden hat, selbst da geht das jetzt nicht mehr, warum auch immer.

Vielleicht wurde da beim letzten update von dem Spiel was geändert.

Stehe auch noch mit jemand anderes aus dem Forum im Kontakt, mal gucken was er noch für Ideen und Tipps für mich hat.

jabu
20.11.2014, 15:06
Irgendwie bin ich etwas stutzig geworden. Bei deinem Reg-Key, also mit {1EAC1D02-C6AC-4FA6-9A44-96258C37C812EU}_is1, hängt doch hinten dieses '_is1' dran. Wenn ich meine Registry so durchgucke, habe ich das ausschließlich bei InnoSetup. Dabei habe ich jedes Mal sehr detaillierte Informationen, z.B.:

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninsta ll\{DDA3C325-47B2-4730-9672-BF3771C08799}_is1]
"Inno Setup: Setup Version"="5.5.1 (a)"
"Inno Setup: App Path"="C:\\Program Files (x86)\\XMedia Recode"
"InstallLocation"="C:\\Program Files (x86)\\XMedia Recode\\"
"Inno Setup: Icon Group"="XMedia Recode"
"Inno Setup: User"="sehpu1"
"Inno Setup: Selected Tasks"="desktopicon"
"Inno Setup: Deselected Tasks"=""
"Inno Setup: Language"="german"
"DisplayName"="XMedia Recode Version 3.1.6.6"
"UninstallString"="\"C:\\Program Files (x86)\\XMedia Recode\\unins001.exe\""
"QuietUninstallString"="\"C:\\Program Files (x86)\\XMedia Recode\\unins001.exe\" /SILENT"
"DisplayVersion"="3.1.6.6"
"Publisher"="XMedia Recode"
"URLInfoAbout"="http://www.xmedia-recode.de/"
"HelpLink"="http://www.xmedia-recode.de/"
"URLUpdateInfo"="http://www.xmedia-recode.de/"
"NoModify"=dword:00000001
"NoRepair"=dword:00000001
"InstallDate"="20140322"
"MajorVersion"=dword:00000003
"MinorVersion"=dword:00000001
"EstimatedSize"=dword:000049f6
Warum sollte bei der Installation von 'World of Tanks' so wenig gespeichert worden sein? Das leuchtet mir nicht ein.

Nun quick and dirty:


[Setup] //(Auszug)
DefaultDirName={code:GetRegistryPath|{pf}\Hier den Standardpfad eintragen}

[Code[ //Klammer umdrehen, ist nur für's Forum
const
stUninstRegPth = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1EAC1D02-C6AC-4FA6-9A44-96258C37C812EU}_is1';
stUninstRegKey = 'UninstallString';

function GetRegistryPath(DefaultPath: string): string;
var
mypos: Longint;
begin
if (RegQueryStringValue(HKLM, stUninstRegPth, stUninstRegKey, Result)) then begin
Result := Trim(Result);
mypos := Pos('.exe', AnsiLowercase(Result));

if (mypos > 0) then begin
SetLength(Result, mypos);
Result := ExtractFilePath(Result);
Result := RemoveQuotes(Result);
exit;
end;
end;
Result := ExpandConstant(DefaultPath);
end;

Das funktioniert in den meisten Fällen, ist aber nicht ganz frei von Nebeneffekten, z.B. wenn '.exe' selbst irgendwo im Pfad vorkommt. Damit muss man notfalls leben. Im Gegenzug werden Parameter abgeschnitten, weshalb das etwas universeller verwendbar wird. Wenn du das ganz sicher nicht brauchst, kannst du es weglassen. Alternativ kann man, falls sicher ist, dass ein optionaler Parameter stets mit einem Slash und nicht mit einem Backslash beginnt, von hinten her bis vor diese Position herunterkürzen. Leider fehlt in diesem Pascal-Dialekt PosEx, weshalb man den Zeiger nicht weiterschieben kann. Selbstgestrickte Algorithmen sind oft nicht für MBCS sicher, aber die von dieser Teilmenge von Pascal sind es größtenteils auch nicht.

Um einen Pfad einigermaßen sicher auszuwerten, muss man schon fast einen Kommandozeileninterpreter schreiben. Ich habe zusätzlich noch eine ziemlich komplexe Version erstellt (nicht ganz fertig), die sich beinahe wie Windows verhält und auch mit ziemlich schrägen Strings fertig wird. Sie sucht den String auf die erste atomare Einheit ab, sodass alles danach als Parameter gewertet wird. Das ist aber alles andere als einfach und trotzdem nicht wasserdicht. Wenn man das haben möchte, müssen natürlich die physischen Verzeichnisse noch vorhanden sein und einzeln abgeprüft werden. Es gibt Situationen, in denen ein Dateiname kaum von einem Verzeichnisnamen zu unterscheiden ist, es sei denn, man priorisiert und prüft konkret. Selbst Windows reagiert unterschiedlich auf solche Zweideutigkeiten, je nachdem, ob man in einer Batchdatei, in der Konsole oder im Explorer probiert.

Grand
02.12.2014, 08:52
Hi,

hab es damit mal probiert, funktioniert leider auch nicht, der Installationspfad bleibt dann leer.

Sorry für die Späte Antwort.

jabu
04.12.2014, 15:36
Vermutlich liegt der Fehler irgendwo im Detail, denn bei mir funktioniert alles, und zwar reproduzierbar.

(Ich verwende den 'Unicode-Build' von 'Inno Setup', denn - grob gesagt - das Windows API der NT-Familie verwendet intern UCS-2 Encoding für Unicode (.NET kann UTF), ANSI mit Codepages ist für Windows 9x. Nicht dass der ANSI-Build irgendwie vom Unicode-Build abweicht, obwohl es nicht sein sollte.)

Um dein Problem nachzuvollziehen bräuchte man wohl dieses von dir:

gesamte .iss-Datei, welche das Setup-Skript enthält
exportierten Reg-Zweig, mit dem das funktionieren soll

Es empfiehlt sich, das zu packen (zip, 7z, rar, gz ...) und zu verlinken. Das kannst du auch im Forum hochladen. Falls dir ein Filehoster zur Verfügung stehen sollte, empfehle ich das.