Create Python EXE without MSVCP90.dll - python

I'm trying to use Py2Exe to take a python program (using wxPython) to a Windows exe but there is an error regarding MSVCP90.dll . After reading py2exe fails to generate an executable on StackOverflow, it says I need to download this file. However, it also says all target users must download this file. This will be a huge inconvenience for my users (mostly corporate clients who will not know how to download the file), so is there a way to package the with the program?
Thanks!

What is MSVCP90.dll
MSVCP90.dll is Multithreaded, dynamic Visual Studio 2008 C Runtime Library. Generally your application should package MSVCP90.dll unless you are sure that the target machine have the matching CRT. You can use any of the packaging software to package the necessary DLLs and your software and distribute it.
Purpose of MSVCP90.dll
You may be wondering why you need this weird dll? Well CRT is nothing new to python. All application that is based on C heavily relies on C library functions. All the implementations of the standard C Library functions like (malloc, strcpy ..) to name a few is implemented in these libraries. There are different kinds and the specific MSDN website have more details on it.
Distributing MSVCP90.dll
When distributing CRT, you should understand that depending upon what CRT you have used the version number which is suffixed with the name of the CRT varies. For example MSVCP90.DLL is the CRT from Visual Studio 2008. A single machine can contain multiple CRTs either in the system folder on in application installation path.
If you are planning to package your application, you need to re-verify, which CRT version your application uses. Packaging wrong CRT or using one can cause undesired and undefined effect. Generally speaking the CRT your Python Installation uses, should be the same CRT you should package.
Determining the correct MSVCRT
As there are different CRT builds with different versions, it is difficult to ascertain, which CRT should be packaged. If you have a running application (executable), you can use dependencywalker to determine the correct version. Right click on any of the DLLs and click on properties and it will show you the location from which this DLL is being picked.
Packaging your application.
You can try using PyInstaller to package your application. It would be a convenient way to get the DLL into the target machine.

You have to deliver your app with that dll in same folder as your exe file.

Related

I cannot build python.dll as a static library (/MTd) using Visual Studio

I am working with the 3.6.4 source release of Python. I have no trouble building it with Visual Studio as a dynamic library (/MDd) I can link the Python .dll to my own code and verify its operation.
But when I build it (and my code) with (/MTd) it soon runs off the rails when I try to open a file with a Python program. A Debug assertion fails in read.cpp ("Expression: _osfile(fh) & FOPEN"). What I believe is happening is the Python .dll is linking with improper system libraries. What I can't figure out is how to get it to link with the correct ones (static libraries).
This is what I needed to do to build and use python statically embedded in another application.
To build the static python library (e.g., python36_d.lib, python36.lib)
Convert ALL projects in the python solution (pcbuild.sln) to static. This is about 40 projects, so it may take awhile. This includes setting library products to be build as 'static lib', and setting all /MD and /MDd build options to /MT and /MTd.
For at least the pythoncore project alter the Preprocess define to be Py_NO_ENABLE_SHARED. This tells the project it will be looking for calls from static libraries.
By hook or crook, find yourself a pyconfig.h file and put it in the Include area of your Python build. It is unclear how this file is built from Windows tools, but one seems to be able to snag one from other sources and it works ok. One could probably grab the pyconfig.h from the Pre-compiled version of the code you are building. [By the way, the Python I built was 3.6.5 and was built with Windows 2015, update 3.]
Hopefully, this should enable you to build both python36.lib and python36_d.lib. Now you need to make changes to your application project(s) to enable it to link with the python library. You need to do this:
Add the Python Include directory to the General->Include Directories list.
Add the Python Library directories to the General->Library Directories lists.
This will be ..\PCBuild\win32 and ..\PCBuild\amd64.
Add the define Py_NO_ENABLE_SHARED to the C/C++ -> Preprocessor area.
For Linker->input add (for releases) python36.lib;shlwapi.lib;version.lib and (for debugs) python36_d.lib;shlwapi.lib;version.lib.
And that should be it. It should run and work. But one more thing. In order to be able to function, the executable needs to access the Lib directory of the python build. So a copy of that needs to be moved to wherever the executable (containing the embedded python) resides. Or you can add the Lib area to the execution PATH for windows. That should work as well.
That's about all of it.

Providing Standard Library for embedded Python

I've successfully embedded Python in a multi-platform C++ project.
This required linking to a libpython, which needs to be provided for each platform I'm targeting. For OSX it was easy, I just pulled it out of some homebrew folder.
But I would like my Python scripts to use imports from the standard library (e.g. this one)
What is that going to involve?
Standard Library documentation for Python 3 says that the standard library is a mix of compiled units and .py files, so I'm expecting I will have to maybe link my project against a second library, and somehow inform the Python runtime of the location of the folder containing the standard library's .py files.
But is it really going to be this simple? Is this process documented anywhere?
Am I going to run into trouble on mobile platforms? It looks as though Kivy might be on their way towards solving this problem...

How do I include 3rd party modules with my python scripts?

I've started using Python to automate repetitive tasks I have at work, and often need to integrate references to third party modules into my scripts. How can I include these files with my scripts directly? I know there are ways to install the libraries centrally in my python installation folder (C:\Python27). Many third party modules provide an EXE installer that will do this automatically. However, I'm concerned how that will affect the portability of my scripts. For example if I send my script to someone else I don't want to also have to send them a list of all the separate modules they need to go download and install.
Update
I have a lot more experience with C# project in Visual Studio. In a visual studio project if I want to use a 3rd party DLL I just include that DLL in my solution in a Lib folder and reference that DLL from my project. I don't bother loading that library into the GAC, which to me seems like the .NET equivalent of installing a python package.
Isn't there some way I can just include 3rd party libraries in my project folder and reference them using a relative path? Say I had the following file structure.
\My Script.py
\lib\3rdPartyLib\3rdPartyLib.py
Can I import 3rdPartyLib from MyScript.py?
import 3rdPartyLib from \lib\3rdPartyLib\ ??????
Why would I not want to do this?
Update:
Yes, you can copy third party modules to your application folder. While using the site-packages folder allows for centralized per-machine updates, if you change the libraries infrequently it might be easier for you to just include them in your application folder as you describe.
If possible, putting your application folders on a network drive will simplify updates network wide.
You'll want to use py2exe or pyinstaller.
It will build a folder full of dependencies and a Windows .exe. You can include icons and other metadata as well. Wrap it in a free installer such as innoSetup and you'll have a profesional looking application on your hands.
Well you can use a py2exe or pyinstaller or you can reference your modules on start of scripts pack them into a archive and have your program portable over different os-es !
But well as much heh I see you only use windows ! What make idea of portability last in your back thought ...

How do I embed a python library in a C++ app?

I've embedded python on a mobile device successfully, but now how do I include a python library such as urllib?
Additionally, how can I include my own python scripts without a PYTHONPATH?
(please note: python is not installed on this system)
The easiest way is to create a .zip file containing all the python code you need and add this to your process's PYTHONPATH environment variable (via setenv()) prior to initializing the embedded Python interpreter. Usage of .pyd libraries can be done similarly by adding them to the same directory as the .zip and including the directory in the PYTHONPATH as well.
Usage of the setenv() call can cause trouble on Windows if you're mixing c-runtime versions. I spent many aggrivating hours learing that setenv() only sets the environment variables for the version of the c-runtime your compiler ships with. So if, for example, Python was built with VC++ 2005 and your compiler is VC++ 2008, you'll need to use an alternative mechanism. Browsing the sources for py2exe and/or PyInstaller may provide you with a better solution (since you're doing essentially the same thing as these tools) but a simple alternative is to "cheat" by using PyRun_SimpleString() to set the module search path from within Python itself.
snprintf(buff, "import sys\nsys.path.append("%s")\n", py_zip_filename)
PyRun_SimpleString(buff)

How does Dropbox use Python on Windows and OS X?

In Windows the Dropbox client uses python25.dll and the MS C runtime libraries (msvcp71.dll, etc). On OS X the Python code is compiled bytecode (pyc).
My guess is they are using a common library they have written then just have to use different hooks for the different platforms.
What method of development is this? It clearly isn't IronPython or PyObjC. This paradigm is so appealing to me, but my CS foo and Google foo are failing me.
Dropbox uses a combination of wxPython and PyObjC on the Mac (less wxPython in the 0.8 series). It looks like they've built a bit of a UI abstraction layer but nothing overwhelming—i.e., they're doing their cross-platform app the right way.
They include their own Python mainly because the versions of Python included on the Mac vary by OS version (and Dropbox supports back to 10.4 IIRC); also, they've customized the Python interpreter a bit to improve threading and I/O behavior.
(I do not work for Dropbox or have any inside knowledge; all I did was read their forums and examine the filenames in site-packages.zip in the Dropbox app bundle.)
For WINDOWS, Dropbox have employed a module similar to py2exe to package all their .py scripts, required libraries, resources etc into the distribution that you have mentioned above (.exe, library.zip, MS C runtime library and python25.dll) so that they can be run without requiring Python installation. Here's a sample code of how you can achieve this with py2exe.
from distutils.core import setup
import py2exe
options = {'py2exe': {
'compressed':1,
'bundle_files': 2,
'dll_excludes': ['w9xpopen.exe']
}}
setup(console=['myapp.py'],options=options)
Please see the tutorial here for more explanation.
PS: the number of files in the distribution can be controlled using the options parameter as shown in the above example.
These guys reverse engineered Dropbox client code
http://www.openwall.com/presentations/WOOT13-Security-Analysis-of-Dropbox/
https://github.com/kholia/dedrop
Indeed they do bundle their own Python 2.5.4 interpreter found at /Applications/Dropbox.app/Contents/MacOS/python. Poking around in /Applications/Dropbox.app/Contents/Resources/lib/python2.5/lib-dynload it looks to be bundled by PyObjC.
I'm no authority on this, but it seems it is exactly as you suggest in the OP:
My guess is they are using a common
library they have written then just
have to use different hooks for the
different platforms
Python25.dll is probably not their application code, it is a dll containing a copy of the python interpreter which can be called from within a windows application. Those pyc files are probably there in some form on windows, but they might be in an archive or obfuscated.
Python is included in OS/X, so it would be possible for them to execute those pyc file without shipping a python, but would not be surprised if they have there own python version lurking in the app bundle.
I don't know how dropbox builds there distributions, but there are several tools to bundle python apps into executable packages. Take a look at py2exe, py2app, and or cx_freeze.
Recently I published an article on reversing the dropbox client on windows. It is available on slideshare.
In short,
On Windows dropbox uses py2exe. py2exe embeds the python dll as a resource within the executable. The compiled python source files aka pyc files are stored as a zip archive appended to the end of the executable (which is called an overlay).
Extracting the zip archive will give you the pyc files, but that is not the end of the story.
The pyc files are encrypted and not decompilable. They are decrypted only when they are loaded by the embedded python interpreter.
However there is a way to not bother too much about the encryption algorithm used. We can
directly grab decrypted code objects from memory letting dropbox do the decryption for us.

Categories

Resources