Hallo,
ich habe schon wieder ein Problem, bei dem ich mich über einen Tipp freuen würde:
Ich arbeite an einer Anwendung, von der unter anderem SVGs ausgegeben werden und die deshalb von cairocffi abhängt. Unter Linux kann ich wohl mit halbwegs gutem Gewissen davon ausgehen, dass Cairo eh installiert ist - unter Windows sehr wahrscheinlich nicht. Bei https://cairocffi.readthedocs.io/en/sta ... on-windows steht, dass es ausreicht, wenn libcairo-2.dll im Pfad liegt. Ich hab die Datei über die Installation von msys64 auf einen Testrechner geholt und wenn ich das Verzeichnis C:\msys64\mingw64\bin dem Pfad hinzufüge, läuft die Anwendung. Wenn ich dieselbe Datei aber an einen Ort im Benutzerverzeichnis kopiere und diesen dem Pfad hinzufüge, - Ich würde die Anwendung gerne so erstellen, dass sie ohne Admin-Rechte benutzt werden kann. - bekomme ich die Fehlermeldung:
cannot load library 'C:\Users\username\.ordner\libcairo-2.dll': error 0x7e
Die Datei wird also gefunden, kann aber nicht benutzt werden. Das ist natürlich eigentlich eher ein Windows-Problem...
Die Anwendung ist ansonsten fertig paketiert und ich kann sie mit pip aus einem extra-index-url-Repository in den User Space installieren. libcairo-2.dll wird dabei auch mitgeliefert und könnte irgendwo hin kopiert werden.
Ich würde mich sehr über einen Hinweis freuen!
Einbinden von libcairo-2.dll
Nun, ich habe aus dem genannten Verzeichnis C:\msys64\mingw64\bin nach und nach alles gelöscht und ausprobiert, ob cairocffi import werden kann.
Neben libcairo-2.dll blieben die folgenden Dateien übrig, ohne die es nicht mehr funktioniert:
libbrotlicommon.dll
libbrotlidec.dll
libbz2-1.dll
libexpat-1.dll
libfontconfig-1.dll
libfreetype-6.dll
libgcc_s_seh-1.dll
libglib-2.0-0.dll
libgraphite2.dll
libharfbuzz-0.dll
libiconv-2.dll
libintl-8.dll
libpcre-1.dll
libpixman-1-0.dll
libpng16-16.dll
libstdc++-6.dll
libwinpthread-1.dll
zlib1.dll
Wenn ich diesen Satz an DLLs komplett habe, funktioniert es und es ist dann auch egal, wo die liegen und wie sie dahin kommen. Das Mitliefern im Paket funktioniert also auch. (Ich teste beim Starten der Anwendung, ob alles an Ort und Stelle ist und kopiere sie ggf. in einen Ordner im Benutzerverzeichnis und füge den der Pfadvariable hinzu:
Für bessere Möglichkeiten wäre ich nach wie vor dankbar. So kommt es mir etwas instabil vor.
Neben libcairo-2.dll blieben die folgenden Dateien übrig, ohne die es nicht mehr funktioniert:
libbrotlicommon.dll
libbrotlidec.dll
libbz2-1.dll
libexpat-1.dll
libfontconfig-1.dll
libfreetype-6.dll
libgcc_s_seh-1.dll
libglib-2.0-0.dll
libgraphite2.dll
libharfbuzz-0.dll
libiconv-2.dll
libintl-8.dll
libpcre-1.dll
libpixman-1-0.dll
libpng16-16.dll
libstdc++-6.dll
libwinpthread-1.dll
zlib1.dll
Wenn ich diesen Satz an DLLs komplett habe, funktioniert es und es ist dann auch egal, wo die liegen und wie sie dahin kommen. Das Mitliefern im Paket funktioniert also auch. (Ich teste beim Starten der Anwendung, ob alles an Ort und Stelle ist und kopiere sie ggf. in einen Ordner im Benutzerverzeichnis und füge den der Pfadvariable hinzu:
Code: Alles auswählen
if os.path.join(basisordner, "dll") not in os.environ["PATH"]:
if os.environ["PATH"][-1:] == os.pathsep:
os.environ["PATH"] += os.path.join(basisordner, "dll") + os.pathsep
else:
os.environ["PATH"] += (
os.pathsep * os.path.join(basisordner, "dll") + os.pathsep
)
Statt ein Unterverzeichnis platziert man die üblicherweise im gleichen Pfad wie die EXE. Denn der wird automatisch beim suchen nach DLLs berücksichtigt. Und zwar such priorisiert. Packst du’s in PATH, dann kann da eine falsche Reihenfolge eine DLL von woanders zuerst laden. Mit allen negativen Konsequenzen.
Zu deinem eigentlichen Problem: das ist unter Windows leider ein clusterfuck. Unter unxoiden kann man die Abhängigkeiten recht einfach mit kommandozeilen-Tools auswerten, und den Graphen, der dabei entsteht, zum kopieren benutzen. Aber unter Windows kenne ich nur das krepelige depends.exe, mit konfuser UI und nicht so ganz auf der Höhe der Zeit: https://www.dependencywalker.com/ Und natürlich nicht automatisierbar
Damit kannst du dir sicher das ausprobieren vereinfachen. Aber ganz ohne händisches ünberarbeiten gehts nicht.
Zu deinem eigentlichen Problem: das ist unter Windows leider ein clusterfuck. Unter unxoiden kann man die Abhängigkeiten recht einfach mit kommandozeilen-Tools auswerten, und den Graphen, der dabei entsteht, zum kopieren benutzen. Aber unter Windows kenne ich nur das krepelige depends.exe, mit konfuser UI und nicht so ganz auf der Höhe der Zeit: https://www.dependencywalker.com/ Und natürlich nicht automatisierbar
Damit kannst du dir sicher das ausprobieren vereinfachen. Aber ganz ohne händisches ünberarbeiten gehts nicht.
Egal ob Windows, Linux oder irgendein anderes System, Du mußt halt alle Deine Abhängigkeiten installieren, entweder, in dem Du ein Komplettpaket schnürst, oder die Bibliotheken als Abhängigkeiten in einem passende Paketierungssystem angibst.
In Deinem gezeigten Code berechnest Du drei mal den DLL-Pfad, das sollte nur einmal passieren.
Ein `in`-Vergleich ist falsch, da damit auch Teilpfade gefunden werden.
In Deinem gezeigten Code berechnest Du drei mal den DLL-Pfad, das sollte nur einmal passieren.
Ein `in`-Vergleich ist falsch, da damit auch Teilpfade gefunden werden.
Code: Alles auswählen
dll_path = os.path.join(basisordner, "dll")
paths = os.environ["PATH"].split(os.pathsep)
if dll_path not in paths:
paths.append(dll_path)
os.environ["PATH"] = os.pathsep.join(dll_path)