Skip to content

Problem with WinUI3 Project #39

Description

@onslauth

Hi,

I have created a project using the new WinUI3 Template in Visual Studio 2022:
image

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?

Activity

  1. henon commented on May 24, 2022

    @henon
    Owner

    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

  2. onslauth commented on May 24, 2022

    @onslauth
    Author

    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?

  3. henon commented on May 24, 2022

    @henon
    Owner

    yes I am talking about https://github.com/pythonnet/pythonnet

    see if it works with WinUI3

  4. henon commented on May 24, 2022

    @henon
    Owner

    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.

  5. onslauth commented on May 24, 2022

    @onslauth
    Author

    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?

  6. henon commented on May 24, 2022

    @henon
    Owner

    Yes. Please post the link to issue you are about to create on their github here so other people with similar issues can follow.

  7. onslauth commented on May 24, 2022

    @onslauth
    Author

    pythonnet/pythonnet#1796

    Thank you for the help.

  8. onslauth commented on May 24, 2022

    @onslauth
    Author

    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?

  9. onslauth commented on May 24, 2022

    @onslauth
    Author

    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:

    image

    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)]
    
  10. reopened this on May 25, 2022
  11. henon commented on May 25, 2022

    @henon
    Owner

    If I were you I would check out the code of SetupPython and single step it in debugger to see exactly which line crashes.

  12. onslauth commented on May 25, 2022

    @onslauth
    Author

    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?

  13. henon commented on May 25, 2022

    @henon
    Owner

    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.

  14. onslauth commented on May 25, 2022

    @onslauth
    Author

    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.

  15. henon commented on May 25, 2022

    @henon
    Owner

    Can you explain why your change works?

  16. onslauth commented on May 25, 2022

    @onslauth
    Author

    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.

  17. henon commented on May 26, 2022

    @henon
    Owner

    and what if you call SetupPython().Wait(); ? wouldn't that work?

  18. henon commented on May 31, 2022

    @henon
    Owner

    by the way, there is a preview package including python 3.10: https://www.nuget.org/packages/Python.Included/3.10.0-preview2

  19. onslauth commented on Jun 15, 2022

    @onslauth
    Author

    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?

  20. henon commented on Jun 15, 2022

    @henon
    Owner

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions