Skip to content

C# .NET windows form example with python calls #318

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
tarpista opened this issue Jan 8, 2017 · 10 comments
Closed

C# .NET windows form example with python calls #318

tarpista opened this issue Jan 8, 2017 · 10 comments

Comments

@tarpista
Copy link

tarpista commented Jan 8, 2017

I would like to ask that would it be possible to have an example .NET winform application which imports some python module, (ie numpy) and makes some call from it? I could not realy find such anywhere, and my trial fails right at the begining with

An unhandled exception of type 'System.ArgumentNullException' occurred in mscorlib.dll

Additional information: Value cannot be null.

Here is my code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Python.Runtime;

public partial class frmMain : Form
{
    public frmMain()
    {
        InitializeComponent();

        PythonEngine.Initialize(); //<- Error occurs here.
    }
}

Error details:
error

@den-run-ai
Copy link
Contributor

Well, you need to provide more info: Python, .NET, Windows versions and bitness. Is Python registered in %path%? Did you set any environment variables such as PYTHONPATH or PYTHONHOME?

Also look at troubleshooting wiki.

@tarpista
Copy link
Author

tarpista commented Jan 9, 2017

I have several versions of pythons on my machine, my main goal was to be able to use one of my conda virtual environments (C:\PythonEnvs\NNDLM_conda) which has version "Python 2.7.13 :: Continuum Analytics, Inc."

If I check the registry entry for .NET version in .../NET Framework Setup/NDP/v4/Full there I have Version = 4.6.01055

I am using Win7 Pro 64 bit. Python is not registered in the path. Unfortunately I could not find any description about which python directory (and how) I should register from the followings I have:

C:\Python27
C:\Python35
C:\Miniconda3
C:\PythonEnvs\NNDLM_conda\

The above error rises when the referenced dll is the one extracted from "pythonnet-2.0-Beta0-clr4.0_140_py27_UCS2_x86.zip".

At my first trial the Python.Runtime.dll was able to be built by using the "python setup.py build_ext --inplace" command, but that one could not be imported by Visual Studio for some reason that I dont remember. Thats why I thought to get an already built dll.

But now something might have changed on my computer, because if I run the "python setup.py build_ext --inplace" command again it gives an error:
error CS0656: Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'

Further on, if I create an environment variable called "PYTHONPATH", with the values of
"C:\Python27;C:\Python27\DLLs;C:\Python27\Lib;C:\Python27\Lib\lib-tk;C:\Python27\Lib\site-packages;"
or
"C:\PythonEnvs\NNDLM_conda;C:\PythonEnvs\NNDLM_conda\DLLs;C:\PythonEnvs\NNDLM_conda\Lib;C:\PythonEnvs\NNDLM_conda\Lib\lib-tk;C:\PythonEnvs\NNDLM_conda\Lib\site-packages;"
the building process fails in either cases with the following error:

Fatal Python error: Py_Initialize: unable to load the file system codec
File "C:\Python27\Lib\encodings_init_.py", line 123
raise CodecRegistryError,
^
SyntaxError: invalid syntax

Current thread 0x00002528 (most recent call first):

and npython.exe just stops working.

Sorry for too long description, I am very new to python... When I found pythonnet I got very happy, I thought this time it became quite general that .net developers still make their guis in C# and do/call their calculations in/from python, but now I am getting the feeling it is only me who wants to use pythonnet in this direction... maybe I will also need fully turn toward python... Anyway, thanks for any help!

@den-run-ai
Copy link
Contributor

den-run-ai commented Jan 11, 2017 via email

@JimSEOW
Copy link

JimSEOW commented Jan 11, 2017

I had similar problem and the wiki does not help me when I get stuck at

PythonEngine.Initialize(); //<- Error occurs here.

Could not load file or assembly 'Python.Runtime, Version=4.0.0.1, Culture=neutral, PublicKeyToken=null' or one of its dependencies

Looking at this does not suggest a way to debug

Building via setup.py will also copy the various output dlls into the correct place

I already check that all the output dlls are in the right place, yet I am not sure how/why the Python.Runtime needs for it to properly Initialize().

=> Perhaps someone can explain WHAT ARE THE STEPS involved in the initialize() step. What could cause the step to fail.

A straight forwards download and run simple example on how to embed will really help to debug how the python environment causes the error above.

FYI: I have no problem getting python to display a winForm, but how to embed as discussed above.

@tarpista
Copy link
Author

Yes, I checked troubleshooting wiki, but could not succeed with it. Finally I found a workaround by using pythonnet in the other direction (as almost everyone does.), ie making .NET calls from python.

Basically now I make my gui in .NET (C#), and import it in python.
In example my C# code looks like this:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace NeuralNetsGUI
{
    public partial class frmMain : Form
    {
        public Action fp_btn_LoadData_Click;

        public frmMain()
        {
            InitializeComponent();
        }

        private void btn_LoadData_Click(object sender, EventArgs e)
        {
            if (fp_btn_LoadData_Click != null)
            {
                new Thread(new ThreadStart(fp_btn_LoadData_Click)).Start(); //Asynchronus call
                //fp_btn_LoadData_Click.DynamicInvoke(); //Synchronous call
            }
        }
    }
}

As a post-build event in Visual Studio, I copy the compiled NeuralNetsGUI.exe file into my python directory, so it is possible to import it in python:

import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("NeuralNetsGUI") 

import System.Windows.Forms as WinForms
import NeuralNetsGUI as NetsGUI
from System import Action


class clsNetsGUI():
    """A class that creates windows form by importing NetsGUI.frmMain()"""

    def __init__(self):
        self.MainForm = NetsGUI.frmMain()
        self.MainForm.fp_btn_LoadData_Click = (Action(self.btn_LoadData_Click)) # <-- this is where I set the event handler function 

        app = WinForms.Application
        app.Run(self.MainForm)

    def btn_LoadData_Click(self):
        """Button click event handler"""
        print("Button clicked!")

def main():
    netsgui = clsNetsGUI()


if __name__ == '__main__':
    main()

@tarpista
Copy link
Author

tarpista commented Feb 1, 2017

I got the solution for the initialization error. I was trying with a different version of Python.Runtime.dll which I got from somewhere else, because the pythonnet solution did not build for me.

Though it wasnt a good idea to do that. Instead I had to make the solution to build. By default it wants to build using mono, but on a windows machine you have to choose DebugWin and x86, that way it should build and work properly.

Another thread about it:
http://stackoverflow.com/questions/11443550/python-net-unable-to-load-python27-dll-with-winforms-but-console-application-wo

@tarpista tarpista closed this as completed Feb 1, 2017
@den-run-ai
Copy link
Contributor

den-run-ai commented Feb 1, 2017 via email

@tarpista
Copy link
Author

tarpista commented Feb 2, 2017

Sure, but it did not help me out.

Actually I realized, that different versions of the Python.Runtime.dll are neccessary for me to let it work.

For the python -> C# direction the pip install pythonnet gets the proper Python.Runtime.dll and clr.pyd files for me.

But for the other direction, C# -> python I have to build the pythonnet solution to have the proper Python.Runtime.dll which can be referenced in a C# project.

This way I got both direction to work, but the dlls are different and only work in one direction, they are not interchangeable!! I mean if I 'copy clr.pyd and Python.Runtime.DLL to PYTHONFOLDER\Lib\site-packages\ or include their location path to search paths' the first direction will not work. Neither if I reference to the piped dll the second direction will fail....

@den-run-ai
Copy link
Contributor

Are you using the same CPython runtime in both cases? If yes, then you should not need 2 different Python.Runtime.DLL.

I'm guessing the issue is the key used to sign the Python.Runtime.DLL to get the strong name.

Can you please confirm that?

@tarpista
Copy link
Author

tarpista commented Feb 3, 2017

Ah, thanks! You are right. Now it works with one and the same dll. I just went to C:\Python27\Scripts\ and typed pip install pythonnet which downloaded the clr.pyd and Python.Runtime.dll into C:\Python27\Lib\site-packages\ directory.

For the python project I set the environment location to C:\Python27\.

For the C# project I added a reference to the C:\Python27\Lib\site-packages\Python.Runtime.dll.

And it simply works.

So basically there was no need to build the solution, that caused me such a confusion. Do you think there are some cases when the above pip install does not work?

Please correct me that my understanding is correct. Since in a C# application it is not possible to set python environment, is the environment set explicitly by adding the reference to the proper Python.Runtime.dll at the proper location (..\Lib\site-packages\Python.Runtime.dll)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants