I have a Python file with as content:
import re
import urllib
class A(object):
def __init__(self, x):
self.x = x
def getVal(self):
return self.x
def __str__(self):
return "instance of A with value '%s'" % (self.getVal())
I also have a simple C# console project with the following code:
engine = Python.CreateEngine();
ScriptSource source = engine.CreateScriptSourceFromFile("test.py");
ScriptScope scope = engine.CreateScope();
ObjectOperations op = engine.Operations;
source.Execute(scope); // class object created
object klaz = scope.GetVariable("A"); // get the class object
object instance = op.Call(klaz, "blabla waarde"); // create the instance
object method = op.GetMember(instance, "getVal"); // get a method
string result = (string)op.Call(method); // call method and get result (9)
Console.WriteLine("Result: " + result); //output: 'Result: blabla waarde'
(I got this from this stackoverflow querstion and answer)
If I leave out the the import urllib statement in the Python file everything works fine. (meaning it finds the re module)
But as soon as i either add import urllib or import urllib2 I get the following exception:
ImportException was unhandled
No module named urllib
So somehow it can't find the urllib. I checked the IronPython lib folder and both urllib and urllib 2 are definitely there.
The same exception gets thrown when I import urllib in the C# code. (engine.ImportModule("urllib");)
Any ideas?
I'd like to manage the imports in the python code and not in the C# code.
(So I'd like to avoid stuff like this: engine.ImportModule("urllib");)
Edit:
Some extra info on what I'm actually going to use this for (maybe someone has an alternative):
I will have a main C# application and the python scripts will be used as extensions or plugins for the main application.
I'm using Python so that I don't need to compile any of the plugins.
I believe that 'Lib' being on sys.path from the interactive console is actually done inside ipy.exe - and when embedding you will have to add the path manually. Either the engine or the runtime has a 'SetSourcePaths' (or similar) method that will allow you to do this.
I face the same problem. Following "Tom E's" suggestion in the comments to fuzzyman's reply I could successfully resolve the issue. The issue seems to be it is not able resolve the location of the urllib.py. We need to set it.
You can check the following link for the question and answer.
The version of CPython you're importing from must match your IronPython version. Use CPython v2.5 for IronPython 2.0, or v2.6 for IronPython 2.6.
Try this:
import sys
sys.path.append(r'\c:\python26\lib') # adjust to whatever version of CPython you have installed.
import urllib
Related
Im trying to import use a python script in C# by using IronPython but an error keeps coming up which I don't understand, seems like it had problems importing the module. The python file runs fine by itself and i tested a simple script that prints "hello" and it worked so I might just be importing the module wrong somehow.
An unhandled exception of type 'System.MissingMemberException' occurred in Microsoft.Dynamic.dll
Additional information: 'module' object has no attribute 'setup'
Error Image
This is the code im trying to run on my C# program
var engine = Python.CreateEngine();
ICollection<string> paths = engine.GetSearchPaths();
string modulePath = #"D:\Python\Lib";
paths.Add(modulePath);
string modulePath2 = #"D:\Python\Lib\site-packages";
paths.Add(modulePath2);
engine.SetSearchPaths(paths);
dynamic py = engine.ExecuteFile(#"broadlink.py");
This is the code in my python
import broadlink
broadlink.setup('*****', '*****', 3)
devices = broadlink.discover(timeout=5)
I need to use a function in Python(32) from dll written in C#.
I use ctypes, but i got the error message:'can't find z function'. The name of the funct i need is 'z' an lib name is "ledscrcons.dll". I've checked it from another app(C#) and this library works good, but python doesn't see it. I have no idea what is the problem??
Here is the code of PScript:
import sys
import string
from time import gmtime, strftime
from array import *
from ctypes import *
import ctypes
import clr
def SendStr(s, port):
mydll = clr.AddReference('ledscrcons.dll')
from ledscrcons import Class1
send = mydll.z
mydll.z.argtypes = [ctypes.c_char_p, ctypes.c_int]
mydll.z.restype = c_int
st = s.encode('cp1251')
i=2
count = 0
critcnt = 1
while i!=0 and count<critcnt:
i=send(c_char_p(st), c_int(port))
if i==2 :
print(str(i) + "dd")
if i==1 :
print(str(i) + 'dd')
if i==0 :
print('t')
count = count + 1
if count==critcnt:
if i==1:
print('kk')
if i==2:
print('uu')
return i
Please,any help would be usefull.
I guess the library you used is not Com Visible. You can make it Com Visible by setting attribute:
[ComVisible(true)]
You can also try IronPython, which is a .net implementation of Python. In IronPython, simply do
import clr
clr.AddReference('YourAssemblyName')
from YourNameSpace import YourClassName
C#-DLLs are not native executables but need the .NET-Runtime library. So you cannot use them with native Python executables. You have to switch to IronPython which is a python implementation in C#.
You cannot use ctypes to access a .NET assembly.
I would recommend using IronPython or Python .NET
I realize that I have to DllImport the perlembed methods
perl_parse
perl_alloc
perl_free
etc.,
But not sure how to marhsall the function arguments for using it with DLLImport especially with perl_parse method.
I also realize that a related question already exists which is almost there but still the OP has solved by created a C wrapper and then using it in C#.
He says that he was not able to DLLimport PERL_SYS_INIT3.
So my question is how to properly wrap them using only C# and use it?
Look at this; I hope it will help (it was called in early version)
I got this from here (perl)
To embed a Perl interpreter in a C# program, add a reference to the COM object "Microsoft Script Control 1.0" and write code like this:
MSScriptControl.ScriptControlClass Interpreter;
Interpreter = new MSScriptControl.ScriptControlClass();
Interpreter.Language = #"PerlScript";
string Program = #"reverse 'abcde'";
string Results = (string)Interpreter.Eval(Program);
The above is equivalent to the following Perl script, which embeds a Perl interpreter within a Perl interpreter:
use Win32::OLE;
my $Interpreter;
$Interpreter = Win32::OLE->new('ScriptControl');
$Interpreter->{Language} = 'PerlScript';
my $Program = "reverse 'abcde'";
my $Results = $Interpreter->Eval($Program);
I want to execute python code from C# with following code.
static void Main(string[] args)
{
ScriptEngine engine = Python.CreateEngine();
ScriptSource source = engine.CreateScriptSourceFromFile(#"F:\Script\extracter.py");
source.Execute();
}
I have the problem at line source.Execute(), I got error "No module named difflib".
What is wrong in my code?
This is my python code (extracter.py).
import re
import itertools
import difflib
print "Hello"
This looks like your engine does not have access to Python standard library - it does not see difflib.py. Either fix the sys.path or copy difflib.py from Python 2.6 to f:\script folder.
re and itertools modules are written in C# and are part of IronPython.modules.dll - that's why importing them work.
Thanks to suggestions from a previous question, I'm busy trying out IronPython, IronRuby and Boo to create a DSL for my C# app. Step one is IronPython, due to the larger user and knowledge base. If I can get something to work well here, I can just stop.
Here is my problem:
I want my IronPython script to have access to the functions in a class called Lib. Right now I can add the assembly to the IronPython runtime and import the class by executing the statement in the scope I created:
// load 'ScriptLib' assembly
Assembly libraryAssembly = Assembly.LoadFile(libraryPath);
_runtime.LoadAssembly(libraryAssembly);
// import 'Lib' class from 'ScriptLib'
ScriptSource imports = _engine.CreateScriptSourceFromString("from ScriptLib import Lib", SourceCodeKind.Statements);
imports.Execute(_scope);
// run .py script:
ScriptSource script = _engine.CreateScriptSourceFromFile(scriptPath);
script.Execute(_scope);
If I want to run Lib::PrintHello, which is just a hello world style statement, my Python script contains:
Lib.PrintHello()
or (if it's not static):
library = new Lib()
library.PrintHello()
How can I change my environment so that I can just have basic statments in the Python script like this:
PrintHello
TurnOnPower
VerifyFrequency
TurnOffPower
etc...
I want these scripts to be simple for a non-programmer to write. I don't want them to have to know what a class is or how it works. IronPython is really just there so that some basic operations like for, do, if, and a basic function definition don't require my writing a compiler for my DSL.
You should be able to do something like:
var objOps = _engine.Operations;
var lib = new Lib();
foreach (string memberName in objOps.GetMemberNames(lib)) {
_scope.SetVariable(memberName, objOps.GetMember(lib, memberName));
}
This will get all of the members from the lib objec and then inject them into the ScriptScope. This is done w/ the Python ObjectOperations class so that the members you get off will be Python members. So if you then do something similar w/ IronRuby the same code should basically work.