Open SecretShop opened 7 years ago
To format your config wrap it with three backticks ( ``` ) before and after.
Do you have tcl86t.dll
and tk86t.dll
in the same directory as your installer.cfg
?
Are your packages and files indented after the first line?
For example
packages = requests
urllib3
chardet
certifi
idna
tkinter
_tkinter
Have you tried with different versions of Python?
I have not tried it with other versions of Python because i do not know how that would effect my code and all of my packages. I included tcl86t.dll
and tk86t.dll
in the same directory on my installer.cfg
I think it is because your Desktop is 64bit and your laptop is 32bit?
Try setting the bitness to 32 bit
http://pynsist.readthedocs.io/en/latest/cfgfile.html#python-section
I have a first gen Surface Pro, i just checked the System specs and i do in fact have 64-bit operating system on both my Desktop and Laptop.
Thanks @Siecje for helping debug this. :-)
That error message usually means that the DLLs are not all for the same bitness. You can run 32-bit applications on a 64-bit operating system, but all the DLLs have to have the same bitness as the exe (python.exe) you're running.
Where did you get the DLLs from? And can you check the bitness of the python.exe it installs in the application?
I got the DLL's from my pythyon36 DLL folder. On the reddit page i refered to this post thinking it could solve my issue: https://www.reddit.com/r/learnpython/comments/5uvlu9/tkinter_could_not_be_found_when_running_project/
BTW, you're using the 'bundled' Python format, which we made the default when you build with Python 3.6+ (and will be the only option at some point in the future). 'Bundled' Python can make much smaller installers than the alternative 'installer' format, but part of the reason for that is that it doesn't include Tkinter by default. So thanks for helping us figure out what's needed to use it with Tkinter!
Here's some info on how to check if a Windows binary file is 32-bit or 64-bit: https://superuser.com/a/889267/209976
Can you try that on the python.exe
and the two DLLs and report the results?
The .exe is x64 tcl86t.dll is x86 tk86t.dll is x86
If you need anything else from me please ask. Thank you very much for all the help.
OK, that's the key. If the exe is x64, it needs x64 DLLs as well, but you've got x86 (32-bit) DLLs.
I think the easiest way for you to fix it is to build with an x86 Python, so you can keep using the same DLLs. You can do that by adding bitness=32
to the Python section of your installer.cfg
.
I changed the bitness=32 and double checked the python.exe and it is in fact x86, but i still get the same errors. I am currently double checking.
EDIT: should the DLL files be in the main directory or should i place them somewhere else? currently they are just included and that's it.
EDIT2: I Triple verified that python.exe and both DLL files are x86.
The DLLs might need to go in the same directory as python.exe
. I would have expected a different error message if it couldn't find them at all, but maybe I'm wrong.
After that, check the bitness of any other DLLs and .pyd
files (which are also DLLs). If they all seem to be x86, the next thing I'd suggest is to investigate with dependency walker.
So i re-installed Python thinking maybe i screwed something up with that and i got some different errors this time around:
EDIT: I am currently trying to copy the TCL folder found in the python directory into my build to fix this.
EDIT2: OMG it works.
Aha, I think that's progress - you're past one error and onto another.
I think what you're trying is the right thing. You might also need to set the TCL_LIBRARY environment variable in Python before importing tkinter.
It is now working, but now i'm trying not to include the 1000+ files of tcl folder.
EDIT: Alright so it needs more than just that one init.tcl file so because i don't wanna find out, i included the whole TCL folder found in the python directory and i placed it in a folder named "lib" which i include while building so that it can actually find the files.
EDIT2: ALRIGHT SO, with the fixes i made... i still have the original issue for some reason where i run the exe, i press the shortcut made by the installer, and nothing happens. Using the Cmd line works, but the shortcut doesn't and i really need that to work so anybody can run it easily. Any help in that area?
Awesome! Could we get you to write up all the pieces you needed to distribute a tkinter application with bundled Python? Perhaps we can even make an example out of it. :-)
For the issue with the shortcut, if it fails to start it should write out a log file with details of any errors that occurred. Have a look at the info here: http://pynsist.readthedocs.io/en/latest/installers.html#uncaught-exceptions
I will definitely write up what is needed when i get the shortcut working.
I found the log file and it gives the following error:
File "C:\Users\SecretShop\Desktop\LoLDataComp\LoLDataComp.launch.pyw", line 30, in <module>
from LoLDataComp import main
File "C:\Users\SecretShop\Desktop\LoLDataComp\pkgs\LoLDataComp.py", line 5, in <module>
import tkinter
File "C:\Users\SecretShop\Desktop\LoLDataComp\pkgs\tkinter\__init__.py", line 36, in <module>
import _tkinter # If this fails your Python may not be configured for Tk
ImportError: DLL load failed: The specified module could not be found.
To clarify, this does not pop up when i run from the Cmd line.
Are you using the TCL_LIBRARY
environment variable, and if so how are you calculating it? Where is the lib
directory you created?
I suspect that you might need to move either the lib folder, or the tcl/tk dlls, or both, to the directory where python.exe
is.
The only difference between the shortcut and running it from cmd
is the current working directory.
If you put the .dll files in the Python directory does it work?
putting the 2 .DLL files in the python directory does not fix the shortcut issue. I just tried that :/
EDIT: Although i do suspect that like my other issue, it is a matter of what directory they should be in.
Is it still the same error in the log file, or a different one?
If we can't find a better way round it, one hackish workaround might be to use os.chdir()
to change the working directory in Python before loading Tkinter. But I hope we can find a neater solution than that.
exact same error in the log file i am afraid.
This seems like the same problem that I had by the of the long discussion
https://github.com/takluyver/pynsist/issues/90#issuecomment-272526072
I thought we added the Python\
directory to PATH
so that the .dll files would be found.
https://github.com/takluyver/pynsist/commit/aea8231005f7925ecf05ab46a6fda7280364b89c
Yup, your PR #101 added that.
@SecretShop can you double check that by printing os.environ('PATH')
before you attempt to load tkinter? Anything printed should go into the same log file as the error, so you can use it for debugging.
Or maybe those DLLs need to go in the pkgs
folder, alongside _tkinter.pyd
.
EYYYYYYYYYYY in pkgs fixed it
EDIT: I'm rebuilding the whole thing to make sure it builds and works properly.
🎉 ✨ 🍰
Okay new issue, how do i make the installer put those .dll files into pkgs
?
im silly i know how
Something like this should do the trick:
files = README.txt
tcl86t.dll > $INSTDIR\pkgs
tk86t.dll > $INSTDIR\pkgs
It works now!
Thanks! It's definitely useful to work out what's needed for a Tkinter app with bundled Python, especially as I'm planning to make bundled Python the only option.
Files or Folders needed and their location in ( )
These files need to be placed into the pynsis_pkgs
folder:
Copy all the contents of tcl
found in the main directory of Python into a folder named lib
in the main installation directory and include it as a file.
Be sure to include the following as packages :
tkinter
_tkinter
Finally, ensure bitness=32
is set since the DLL's are x86
Thanks!
I think copying the tkinter folder to pynsist_pkgs
manually should be equivalent to including tkinter
in the list of packages in the config file. But maybe I've overlooked something.
Does the lib folder go in the main installation directory? So you end up with paths like $INSTDIR\lib\tcl86t.lib
and $INSTDIR\lib\tcl8.6\init.tcl
?
I'm pretty sure you do need _tkinter
included - that refers to the file _tkinter.pyd
, which is imported by the tkinter Python code.
You are correct about copying tkinter i just checked. I removed that and noted it just needs to be included.
Yes and Yes, i clarified up above because i was unclear.
Also yes, i double checked and this does grab that file.
With thanks to pynsist creator @takluyver & to @SecretShop for their inputs on this tkinter issue, here's a pynsist config file for ready-reference of future readers of this thread (might save a few iterations & hours!):
[Application] name=myapp version=0.1832 entry_point=myapppkg.mymodule:myfunction
[Python] version=3.6.1 bitness=32
[Include]
packages=mypkg1 mypkg2 mypkg3 tkinter _tkinter
files = lib tcl86t.dll > $INSTDIR\pkgs tk86t.dll > $INSTDIR\pkgs
Thanks! Would anyone be interested in turning this into an example in the examples directory in the repo?
The ideal would be to include a script which can download and arrange the necessary files (like in the pywebview example), but it would also be a valuable contribution if it uses human-readable instructions on where to find the tcl/tk libraries.
@takluyver I have exactly this requirement for Mu. Folks at the Raspberry Pi Foundation want turtle
available with Mu (and it depends upon tkinter
).
My question: where do I source the dlls needed (tcl86t.dll and tk86t.dll) and I assume they'll work for both 32 and 64bit versions of Python. I've found installers (see: https://www.activestate.com/activetcl/downloads) but all we need, AFAICT, are the dlls. Right..?
EDIT: Scratch that... we need the tcl directory too. :-/ Hmm... could we (pynsist) provide a zip for both 32 and 64 bit tcl dirs..?
You should be able to get the DLLs from a regular Windows installation of Python. The problem for Pynsist is that the 'embeddable zip file' builds we're using don't include Tkinter.
I don't know how Python loads the tcl/tk DLLs, but I would assume they need to match the bitness of the Python interpreter.
OK... I'm in London today (away from my sacrificial Windows laptop), but will have a go tomorrow and let you know how I get on.
Thanks. I may try to investigate it as well.
My current thinking (pending actual work on a Windows machine) is:
tkinter
and _tkinter
are packages (EDIT: in the build config).tcl
directory and dlls.The requirement for downloads means that you could still build this on, say, a Linux box. We'd need to host them somewhere (as files associated with this project perhaps..?).
Thoughts..?
Sounds good to me. We'll also need to make the _tkinter
extension module available somewhere for each version of Python we want to support.
My strategy for hosting some files previously has been to put them in an orphan branch in this repository, make a tag, and then use RawGit for the download URLs. An alternative might be to pack them into wheels and use PyPI for hosting.
Ugh... so this is proving problematic. I suspect part of this is because I'm doing this work on Linux (although pynsist should work on non-WIndows platforms).
Here's what I've done so far:
tcl
directory and tcl86t.dll
and tk86t.dll
files. tkinter
stuff should go where on the users filesystem AFTER they've installed the package._tkinter
and tkinter
as packages in the config file for pynsist, it complains:nsist.copymodules.ExtensionModuleMismatch: Found an extension module that will not be usable on Windows:
/home/ntoll/.virtualenvs/mufoo/lib/python3.6/lib-dynload/_tkinter.cpython-36m-x86_64-linux-gnu.so
Put Windows packages in pynsist_pkgs/ to avoid this.
tkinter
and possibly turtle
for Windows needs to be used rather than the native version (for me on Linux).Ugh... "HELP"...!?!?!?
tl;dr - once I know what needs to go where in the installed application so that it actually works, then I can work backwards from that to know what things need to be downloaded and copied into the correct locations.
Also, when I try building the installer for Mu on Windows, well, you'll see here... ;-)
https://ci.appveyor.com/project/carlosperate/mu/build/1.0.788
388 Traceback (most recent call last):
389 File "c:\python36\lib\runpy.py", line 193, in _run_module_as_main
390 "__main__", mod_spec)
391 File "c:\python36\lib\runpy.py", line 85, in _run_code
392 exec(code, run_globals)
393 File "C:\Python36\scripts\pynsist.exe\__main__.py", line 9, in <module>
394 File "c:\python36\lib\site-packages\nsist\__init__.py", line 513, in main
395 InstallerBuilder(**args).run(makensis=(not options.no_makensis))
396 File "c:\python36\lib\site-packages\nsist\__init__.py", line 471, in run
397 self.copy_extra_files()
398 File "c:\python36\lib\site-packages\nsist\__init__.py", line 412, in copy_extra_files
399 shutil.copy2(file, self.build_dir)
400 File "c:\python36\lib\shutil.py", line 257, in copy2
401 copyfile(src, dst, follow_symlinks=follow_symlinks)
402 File "c:\python36\lib\shutil.py", line 120, in copyfile
403 with open(src, 'rb') as fsrc:
404FileNotFoundError: [Errno 2] No such file or directory: ''
:-/
Although I notice the lib
directory containing the contents of tcl
hasn't found its way onto the branch. :-/
With the lib
directory, I still get the same "No such file or directory: ''" error. :-(
I'm not sure how to proceed until I know what the geography of a known-to-be-working application should look like in terms of tkinter.
Apologies for the noise... that final error is because I put the lib
on its own line (thus creating an empty entry where the \n
was after files=
)
Link to Reddit where problem started: https://www.reddit.com/r/Python/comments/6txk3x/pynsist_troubles_with_running/
The following is my installer.cfg file
So i have my desktop and a laptop, and my desktop has python and everything on it to work with python. So every time i want to test to see if the program runs i put it on my laptop since it doesn't have python and i wanna make sure it works in that environment.
The following is the error message i get whenever i use command line to run "python\python.exe LolDataComp.launch.pyw":