У меня проблема со скриптом, который я встроил в исполняемый файл с помощью PyInstaller. Сценарий прекрасно работает при запуске в качестве Python сценария, но при запуске в качестве приложения PyInstaller он завершается ошибкой, когда обнаруживает файл, путь которого длиннее 260 символов.
Я понимаю, что это связано с ограничение Windows и поддержка более длинных путей должны быть включенными в как в реестре, так и с использованием манифеста приложения, который включает параметр longPathAware
. Кстати, причина, по которой это работает в самой Python, заключается в том, что при Python 3.6 разработчики включили эту настройку для python.exe
и pythonw.exe
.
Пока я сделал все это, и это действительно работает, если я помещаю следующий файл манифеста вместе со встроенным приложением PyInstaller (используя режим --onefile
):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
</assembly>
Однако, чтобы приложение оставалось автономным и переносимым для завершения пользователи, я пытаюсь избежать необходимости использовать внешний файл манифеста и вместо этого заставить PyInstaller встроить этот пользовательский манифест в исполняемый файл.
Опция --manifest
якобы делает это - в по крайней мере, начиная с PyInstaller 3.5, согласно changelog и PR # 3746 :
- (Windows) Fix UA C в одном режим файла путем встраивания манифеста. ( # 1729 , # 3746 )
Но при указании пользовательский файл манифеста, похоже, игнорируется, так как приложение продолжает сбой на длинных путях без установленного внешнего файла манифеста и проверки связанного файла манифеста в режиме --onedir
, он просто выглядит так, как будто он проигнорировал пользовательский и создал этот вместо:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<dependency>
<dependentAssembly>
<assemblyIdentity language="*" name="Microsoft.Windows.Common-Controls" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" type="win32" version="6.0.0.0"/>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"/>
</dependentAssembly>
</dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
</assembly>
Я делаю или понимаете что-то не так? Опция --manifest
не делает то, что я думаю, что должен? Это ошибка?
Этот ответ описывает изменение исходного кода PyInstaller для переопределения создания встроенного манифеста. Это все еще необходимо?
Я также натолкнулся на проект на GitHub, который, похоже, имеет ту же проблему; автор этого PR заявляет:
Обратите внимание, что PyInstaller еще не понимает настройку longPathAware
и удаляет ее из манифеста.
Я не знаю, правда ли это, но я думаю, что это придает некоторый вес этой ошибке.
Я использую PyInstaller 3.6, Python 3.7.2 и Windows 10 версии 1809