PyInstaller Kivy 应用程序找不到数据库后的 NSIS
NSIS after PyInstaller Kivy app can't find database
我成功地使用 PyInstaller 和我的 app.exe 运行 为 Windows 打包了我的 Kivy 应用程序,没有任何问题。 (.spec: )
为了便于分发,我想将我的文件打包成一个独立的 .exe。我的 .nsi 文件:
SilentInstall silent
Section
InitPluginsDir
Setoutpath KanjiOrigin
File /r "dist\KanjiOrigin\*"
ExecWait "dist\KanjiOrigin\KanjiOrigin.exe"
Setoutpath $TEMP
SectionEnd
A .exe 构建无误:http://pastebin.com/h91jzGgY
然而,当 运行ning 这个由 NSIS 制作的 .exe 时,应用程序 运行s 直到我需要连接到我位于 data\db\Kanji-story.db
的内部数据库,但找不到。 (打开.exe的时候在里面,所以数据库已经包含了)
sqlite3.OperationalError: unable to open database: data\db\Kanji-story.db
当我用 7zip 解压缩我的 .exe 并尝试从 PyInstaller 运行 KanjiOrigin.exe 时,我收到以下错误:D:\path\KanjiOrigin\KanjiOrigin.exe is not a valid Win32 application
。 (不确定这是否相关)。
编辑 2
我不知道发生了什么变化,但是现在用 7zip 打开 NSIS .exe 时,提取 PyInstaller .exe 时不会再出现错误。
但是,当尝试 运行 提取的 PyInstaller .exe 时,出现以下错误:
PyInstaller Bootloader 3.x
LOADER: executable is D:\path\KanjiOrigin\KanjiOrigin.exe
LOADER: homepath is D:\path\KanjiOrigin
LOADER: _MEIPASS2 is NULL
LOADER: archivename is D:\path\KanjiOrigin\KanjiOrigin.exe
LOADER: pyi_arch_check_cookie failed
LOADER: archivename is D:\path\KanjiOrigin\KanjiOrigin.pkg
LOADER: Cannot open archive: D:\path\KanjiOrigin\KanjiOrigin.pkg
Cannot open self D:\path\KanjiOrigin\KanjiOrigin.exe or archive D:\path\KanjiOrigin\KanjiOrigin.pkg
此外,包含的数据库似乎没有损坏,因为提取后我可以使用 sqlitebrowser (http://sqlitebrowser.org/) 成功打开它。
我做错了什么?是Setoutpath $TEMP
吗?
编辑:
如果我在 NSIS 创建的 .exe 之外手动包含具有相同文件夹结构 (data\db\Kanji-story.db
) 的数据库,它能找到数据库吗?为什么它能找到外部数据库,但找不到 NSIS .exe 中包含的内部数据库?
看起来你只是从某个地方复制了一些代码,但没有理解它。
SilentInstall silent
Section
InitPluginsDir
SetOutPath $Pluginsdir ; This must be a full path
File myapp.exe
ExecWait '"$pluginsdir\myapp.exe"' ; This should be a full path as well.
SetOutPath $TEMP
SectionEnd
对于临时提取 .exe 然后从 %Temp% 文件夹中执行它的代码来说是典型的,但您不会在安装程序中执行此操作,只有在您创建可移植应用程序包装器时才这样做。
您代码中的另一个问题是您只使用了相对路径。来自 SetOutPath
的文档:
Must be a full pathname, usually is just $INSTDIR
至于 SetOutPath $TEMP
的作用; SetOutPath 在内部设置进程的当前目录,当应用程序处于 运行 时无法删除当前目录,因此最后将其设置为 $TEMP 只是 only 的解决方法如果您使用 SetOutPath $PluginsDir
则需要使用它,因为您希望 NSIS 能够在它退出之前删除 $PluginsDir。
如果您正在使用 NSIS 编写可移植应用程序包装器,那么您应该确保您使用的是完整路径,然后它应该可以工作。另一方面,如果你正在编写一个普通的安装程序,那么你不应该处理 $PluginsDir,你应该使用 SetOutPath $InstDir
并且 InstallDir
属性应该设置为类似于 "$ProgramFiles\MyApp
我成功地使用 PyInstaller 和我的 app.exe 运行 为 Windows 打包了我的 Kivy 应用程序,没有任何问题。 (.spec:
为了便于分发,我想将我的文件打包成一个独立的 .exe。我的 .nsi 文件:
SilentInstall silent
Section
InitPluginsDir
Setoutpath KanjiOrigin
File /r "dist\KanjiOrigin\*"
ExecWait "dist\KanjiOrigin\KanjiOrigin.exe"
Setoutpath $TEMP
SectionEnd
A .exe 构建无误:http://pastebin.com/h91jzGgY
然而,当 运行ning 这个由 NSIS 制作的 .exe 时,应用程序 运行s 直到我需要连接到我位于 data\db\Kanji-story.db
的内部数据库,但找不到。 (打开.exe的时候在里面,所以数据库已经包含了)
sqlite3.OperationalError: unable to open database: data\db\Kanji-story.db
当我用 7zip 解压缩我的 .exe 并尝试从 PyInstaller 运行 KanjiOrigin.exe 时,我收到以下错误:D:\path\KanjiOrigin\KanjiOrigin.exe is not a valid Win32 application
。 (不确定这是否相关)。
编辑 2
我不知道发生了什么变化,但是现在用 7zip 打开 NSIS .exe 时,提取 PyInstaller .exe 时不会再出现错误。 但是,当尝试 运行 提取的 PyInstaller .exe 时,出现以下错误:
PyInstaller Bootloader 3.x
LOADER: executable is D:\path\KanjiOrigin\KanjiOrigin.exe
LOADER: homepath is D:\path\KanjiOrigin
LOADER: _MEIPASS2 is NULL
LOADER: archivename is D:\path\KanjiOrigin\KanjiOrigin.exe
LOADER: pyi_arch_check_cookie failed
LOADER: archivename is D:\path\KanjiOrigin\KanjiOrigin.pkg
LOADER: Cannot open archive: D:\path\KanjiOrigin\KanjiOrigin.pkg
Cannot open self D:\path\KanjiOrigin\KanjiOrigin.exe or archive D:\path\KanjiOrigin\KanjiOrigin.pkg
此外,包含的数据库似乎没有损坏,因为提取后我可以使用 sqlitebrowser (http://sqlitebrowser.org/) 成功打开它。
我做错了什么?是Setoutpath $TEMP
吗?
编辑:
如果我在 NSIS 创建的 .exe 之外手动包含具有相同文件夹结构 (data\db\Kanji-story.db
) 的数据库,它能找到数据库吗?为什么它能找到外部数据库,但找不到 NSIS .exe 中包含的内部数据库?
看起来你只是从某个地方复制了一些代码,但没有理解它。
SilentInstall silent
Section
InitPluginsDir
SetOutPath $Pluginsdir ; This must be a full path
File myapp.exe
ExecWait '"$pluginsdir\myapp.exe"' ; This should be a full path as well.
SetOutPath $TEMP
SectionEnd
对于临时提取 .exe 然后从 %Temp% 文件夹中执行它的代码来说是典型的,但您不会在安装程序中执行此操作,只有在您创建可移植应用程序包装器时才这样做。
您代码中的另一个问题是您只使用了相对路径。来自 SetOutPath
的文档:
Must be a full pathname, usually is just $INSTDIR
至于 SetOutPath $TEMP
的作用; SetOutPath 在内部设置进程的当前目录,当应用程序处于 运行 时无法删除当前目录,因此最后将其设置为 $TEMP 只是 only 的解决方法如果您使用 SetOutPath $PluginsDir
则需要使用它,因为您希望 NSIS 能够在它退出之前删除 $PluginsDir。
如果您正在使用 NSIS 编写可移植应用程序包装器,那么您应该确保您使用的是完整路径,然后它应该可以工作。另一方面,如果你正在编写一个普通的安装程序,那么你不应该处理 $PluginsDir,你应该使用 SetOutPath $InstDir
并且 InstallDir
属性应该设置为类似于 "$ProgramFiles\MyApp