Python.Included
Python.Included copied to clipboard
Problem with WinUI3 Project
Hi,
I have created a project using the new WinUI3 Template in Visual Studio 2022:

Trying to use Python.Included, I receive the following error in the debug output:
Exception thrown at 0x00007FFF99A34FD9 in WinUI3PythonIncluded.exe: Microsoft C++ exception: EEMessageException at memory location 0x000000DF2519D450.
Exception thrown: 'System.DllNotFoundException' in Python.Runtime.dll
The project can be found here https://github.com/onslauth/WinUI3PythonIncluded.
Creating a normal console application with Python.Included works fine.
Do you perhaps have any suggestions that I can try to resolve the problem?
Try if you can get pythonnet to work directly (Python.Included is just a deployment solution for pythonnet). See if it throws the same exception. That should give you more insights
Are you talking about
https://github.com/henon/pythonnet_netstandard or https://github.com/pythonnet/pythonnet ?
If I understand you correctly, I want to be looking at the following file: https://github.com/henon/Python.Included/blob/master/Python.Included/Installer.cs
Is that correct?
yes I am talking about https://github.com/pythonnet/pythonnet
see if it works with WinUI3
If I understand you correctly, I want to be looking at the following file: https://github.com/henon/Python.Included/blob/master/Python.Included/Installer.cs
Is that correct?
Only if we assume that the deployment didn't work. But there is no indication of that yet.
I have installed the embedded python to the folder C:\Python\
I have also created a new WinUI3 template program to test the code and tested both inside a task and without:
private async Task TestPython( )
{
using ( Py.GIL( ) )
{
dynamic sys = Py.Import( "sys" );
}
}
private void myButton_Click( object sender, RoutedEventArgs e )
{
myButton.Content = "Clicked";
Runtime.PythonDLL = "C:\\Python\\python310.dll";
Task.Run( ( ) => this.TestPython( ) );
}
and
private void myButton_Click( object sender, RoutedEventArgs e )
{
myButton.Content = "Clicked";
Runtime.PythonDLL = "C:\\Python\\python310.dll";
using ( Py.GIL( ) )
{
dynamic sys = Py.Import( "sys" );
}
}
They both fail to run with the following errors respectively:
'WinUI3Pythonnet.exe' (Win32): Loaded 'C:\python\python310.dll'.
'WinUI3Pythonnet.exe' (Win32): Loaded 'C:\Windows\System32\vcruntime140.dll'.
Exception thrown at 0x00007FFE9C055F68 (python310.dll) in WinUI3Pythonnet.exe: 0xC0000005: Access violation reading location 0x0000000000000010.
'WinUI3Pythonnet.exe' (Win32): Loaded 'C:\python\python310.dll'.
'WinUI3Pythonnet.exe' (Win32): Loaded 'C:\Windows\System32\vcruntime140.dll'.
Exception thrown at 0x00007FFE9B25FA7D (python310.dll) in WinUI3Pythonnet.exe: 0xC0000005: Access violation reading location 0x0000000000000011.
I expect I need to take this up further with the pythonnet developers?
Yes. Please post the link to issue you are about to create on their github here so other people with similar issues can follow.
With help from the Pythonnet developers, the program now runs.
The solution can be found here: https://github.com/onslauth/WinUI3-Pythonnet
Is there something else you would like me to try with regards to getting Python.Included working?
I've had some time to play around now.
I updated the nuget package to: 3.10.0-preview1 so that I can directly set the PythonDLL property.
During Installer.SetupPython( ) it seems to crash or hang or something in this step breaks.
I changed my code to the following:
Installer.InstallPath = @"C:\Testing\";
string python_dll_path = Path.Combine( Installer.EmbeddedPythonHome, "python310.dll" );
var task = Installer.SetupPython( );
Task.WhenAll( task );
Runtime.PythonDLL = python_dll_path;
PythonEngine.Initialize( );
using ( Py.GIL( ) )
{
dynamic sys = Py.Import( "sys" );
string version = sys.version;
System.Diagnostics.Debug.WriteLine( "VERSION: {0}", version, null );
}
When I run the program for the first time when the C:\Testing directory is empty, it will extract the zip file to the directory, and create the directory python-3.10.0-embed-amd64. However it crashes at this point and even manages to crash the Visual Studio Debugger. It also appears that something happened during extraction:

If I extract the contents of the zip file python-3.10.0-embed-amd64.zip into C:\Testing\python-3.10.0-embed-amd64 and run the program again, everything now works correctly:
VERSION: 3.10.0 (tags/v3.10.0:b494f59, Oct 4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)]
If I were you I would check out the code of SetupPython and single step it in debugger to see exactly which line crashes.
Hi,
I have managed to track the problem down to line 92 in Python.Deployment Installer.cs, specifically this line:
ZipFile.ExtractToDirectory(zip, zip.Replace(".zip", "") );
Even though the code is in a try/catch section, it seems to bypass that.
I have also tested the above code in a new WinUI 3 Template project, and everything works fine without issue:
private async void myButton_Click( object sender, RoutedEventArgs e )
{
myButton.Content = "Clicked";
var zip_file = "C:\\Testing\\python-3.10.0-embed-amd64.zip";
string zip_path = "C:\\Testing\\python-3.10.0-embed-amd64";
await Task.Run( ( ) =>
{
try
{
ZipFile.ExtractToDirectory( zip_file, zip_file.Replace( ".zip", "" ) );
}
catch ( Exception e )
{
System.Diagnostics.Debug.WriteLine( "\n\n\n{}\n\n\n", e, null );
}
} );
}
If I then run the WinUI3 project with Python.Included in it, after running the above project and letting it extract the zip file, everything works correctly.
Is there anything else you would like me to try or test?
I have no idea why the same line of code works in your app but not when called via the nuget or link the python included code base.
Hi @henon
I have had some time to play with the code, and found a solution for you.
The following seems to work without problems:
var task = Task.Run( ( ) =>
{
try
{
ZipFile.ExtractToDirectory( zip, zip.Replace( ".zip", "" ) );
var pth = Path.Combine(EmbeddedPythonHome, Source.GetPythonVersion() + "._pth");
File.Delete(pth);
}
catch ( Exception e )
{
Log("SetupPython: Error extracting zip file: " + zip);
}
} );
task.Wait( );
Please let me know if you require any further testing from me.
Can you explain why your change works?
Sorry, I have absolutely no idea. I've only been writing C# for about 2 months.
I also tried the following:
await Task.WhenAll( task );
Anything with the await seems to cause it to break.
Hope that helps.
One last thing I noticed when going through the code for the main branch, you haven't updated the download URL to 3.10.
In Python.Deployment -> Installer.cs:52:
public static InstallationSource Source { get; set; } = new DownloadInstallationSource() { DownloadUrl = @"https://www.python.org/ftp/python/3.7.3/python-3.7.3-embed-amd64.zip" };
Thank you for all the help.
and what if you call SetupPython().Wait(); ? wouldn't that work?
by the way, there is a preview package including python 3.10: https://www.nuget.org/packages/Python.Included/3.10.0-preview2
Hi,
Sorry, I've been a bit busy.
I will try the updated package and let you know. I see that you only changed the version number of the python used, and nothing further has been done regarding this issue?
Yes I did not change anything else. Since this seems to be a problem with await in your app I see no reason to change SetupPython from async to blocking because you can call the SetupPython method blockingly yourself like this: SetupPython().Wait();
Where would be the difference between me calling Wait() inside of SetupPython and you calling it on your side? The effect should be the same. Please try and let me know.