Python for .NET "unable to find assembly" error
Asked Answered
D

7

22

I'm using CPython and I have a C# dll. I'm trying to use Python for .NET to make them talk. I can't use IronPython because I need to integrate this into an existing CPython system.

I'm completely new to Python for .NET, and I actually have very little experience with Python and no experience with C#. So please forgive me if my question seems very basic.

I'm using Python 2.7.3, and I downloaded pythonnet-2.0-alpha2-clr2.0_131_py27_UCS2 and unzipped it into a folder named pyfornet_test, which also contains the dll I'm trying to use (called DotNet4Class.dll)

Then I run this:

import sys

import os

import clr

sys.path.append(r"C:\pyfornet_test")

clr.AddReference("DotNet4Class.dll")

Which gives me this error:

System.IO.FileNotFoundException: Unable to find assembly 'DotNet4Class.dll'.
   at Python.Runtime.CLRModule.AddReference(String name) in C:\Users\Barton\Documents\Visual Studio 2008\Projects\PyShar
p\trunk\pythonnet\src\runtime\moduleobject.cs:line 375

Any advice would be much appreciated. Thank you!

Determinative answered 6/11, 2012 at 21:22 Comment(0)
B
7

Is DotNet4Class.dll built against .NET 4? I assume so based on the naming of the dll.

Note the issue here: http://sourceforge.net/tracker/?func=detail&aid=3293169&group_id=162464&atid=823891

clr.AddReference fails when assembly is built with .NET 4.0 - ID: 3293169

I'd read the solution, but essentially, you need to rebuild and recompile the python for .NET project under .NET 4.

I'll also mention that projects like this, that aren't actively developed and used by lots of people, generally have subtle idiosyncrasies that make knowledge of the platform essential to work around problems such as this. It sounds like you're trying to hack this solution in without understanding much about python or .NET which is always going to be fraught with problems.

Brawley answered 6/11, 2012 at 21:47 Comment(9)
Josh, your analysis of the situation is spot-on. I was hoping that this process would be as easy as using a C dll with the help of ctypes, which I was able to do without knowing much of anything, but clearly that's not the case.Determinative
I did try the solution at the link you posted. I got as far as downloading the projects in Subversion; none of them loaded correctly in VS. Peeling this onion may take more time than I have.Determinative
@Determinative It looks like a fairly old project. The documentation even mentions using IronPython. Can I ask what you're trying to accomplish? There may be better solutions available.Brawley
I'm automating a piece of lab equipment. The only dll provided is C#. I'm trying to integrate this into an existing system that uses CPython. The two solutions I know of are 1)Python for .NET, and 2)exporting the C# functionality as a COM object. I only have the most vague idea of what #2 means, so I went with #1. I would love to hear other ideas.Determinative
There are two options that I see.. 1: Write a device driver in C or python. We had to do this for medical equipment in a uni project, and it could take awhile. The second and probably easier solution is to create a small .NET service and use either HTTP or some kind of Message Broker (RabbitMQ or ZeroMQ or Redis) to communicate between the python application and the device service.Brawley
Hmmm, I don't understand most of what you're saying. Probably not a good sign. I think what I'm going to do is try to automate this in C# to meet my immediate need, and at some point in the future perhaps I can integrate it with our Python system. Granted, I don't know C#, but working with one language I don't know will be easier than two languages I don't know and a link between them that I don't understand.Determinative
@Annie, what I'm suggesting is creating a web project in c# (or a project using Message Queues instead of Web, but don't worry about that for now). That C# website will use the c# binding to your device to control the device. Then you can control the device from a web browser, simply by visiting a page or POSTing data to the URL. Then you simply get your CPython to POST data to the website, which in turn controls the device, and returns a response back to CPython. It's an indirect way of calling the C# from Python.Brawley
I updated VS and have now been able to solve the original posted problem, so I'm marking this as the solution. Thank you, Josh.Determinative
PythonNet 2.3 loads a .NET 4 DLL fine. But with my .NET 4 DLL, I was also getting the error "Unable to find assembly" error. My issue is that my DLL was built for x86, and my CPython was x64. Changing my Python to x86 fixed the problem. In short, the error "Unable to find assembly" means "Unable to load the assembly".Judoka
T
19

One reason can be Windows was not enabling it to load from "external sources". To fix this:

  • Right-click on the .dll
  • "Properties"
  • Under "General", click "Unblock"
Transpacific answered 14/10, 2019 at 8:56 Comment(3)
This was my issue too! It's a frustratingly silent and hidden property of the dll.Klingel
This was my issue as well. Unfortunately, I tried this after an unnecessary 32-bit python version to check.Stenophyllous
good bless you!Huonghupeh
A
18

Try this (without extension .dll):

clr.AddReference(r"C:\pyfornet_test\DotNet4Class")
Arrangement answered 24/4, 2013 at 6:58 Comment(0)
B
7

Is DotNet4Class.dll built against .NET 4? I assume so based on the naming of the dll.

Note the issue here: http://sourceforge.net/tracker/?func=detail&aid=3293169&group_id=162464&atid=823891

clr.AddReference fails when assembly is built with .NET 4.0 - ID: 3293169

I'd read the solution, but essentially, you need to rebuild and recompile the python for .NET project under .NET 4.

I'll also mention that projects like this, that aren't actively developed and used by lots of people, generally have subtle idiosyncrasies that make knowledge of the platform essential to work around problems such as this. It sounds like you're trying to hack this solution in without understanding much about python or .NET which is always going to be fraught with problems.

Brawley answered 6/11, 2012 at 21:47 Comment(9)
Josh, your analysis of the situation is spot-on. I was hoping that this process would be as easy as using a C dll with the help of ctypes, which I was able to do without knowing much of anything, but clearly that's not the case.Determinative
I did try the solution at the link you posted. I got as far as downloading the projects in Subversion; none of them loaded correctly in VS. Peeling this onion may take more time than I have.Determinative
@Determinative It looks like a fairly old project. The documentation even mentions using IronPython. Can I ask what you're trying to accomplish? There may be better solutions available.Brawley
I'm automating a piece of lab equipment. The only dll provided is C#. I'm trying to integrate this into an existing system that uses CPython. The two solutions I know of are 1)Python for .NET, and 2)exporting the C# functionality as a COM object. I only have the most vague idea of what #2 means, so I went with #1. I would love to hear other ideas.Determinative
There are two options that I see.. 1: Write a device driver in C or python. We had to do this for medical equipment in a uni project, and it could take awhile. The second and probably easier solution is to create a small .NET service and use either HTTP or some kind of Message Broker (RabbitMQ or ZeroMQ or Redis) to communicate between the python application and the device service.Brawley
Hmmm, I don't understand most of what you're saying. Probably not a good sign. I think what I'm going to do is try to automate this in C# to meet my immediate need, and at some point in the future perhaps I can integrate it with our Python system. Granted, I don't know C#, but working with one language I don't know will be easier than two languages I don't know and a link between them that I don't understand.Determinative
@Annie, what I'm suggesting is creating a web project in c# (or a project using Message Queues instead of Web, but don't worry about that for now). That C# website will use the c# binding to your device to control the device. Then you can control the device from a web browser, simply by visiting a page or POSTing data to the URL. Then you simply get your CPython to POST data to the website, which in turn controls the device, and returns a response back to CPython. It's an indirect way of calling the C# from Python.Brawley
I updated VS and have now been able to solve the original posted problem, so I'm marking this as the solution. Thank you, Josh.Determinative
PythonNet 2.3 loads a .NET 4 DLL fine. But with my .NET 4 DLL, I was also getting the error "Unable to find assembly" error. My issue is that my DLL was built for x86, and my CPython was x64. Changing my Python to x86 fixed the problem. In short, the error "Unable to find assembly" means "Unable to load the assembly".Judoka
H
5

I have code like this (I copied MyRightClickMenuService.dll to the same directory as my script.py). It is built against .Net 4.0.

# script.py
import clr
import os
import sys
sys.path.append(os.path.dirname(__file__))

clr.AddReference('MyRightClickMenuService')
clr.AddReference('System')
clr.AddReference('System.Security')

from MyRightClickMenuService import (
    AclSecuredNamedPipeBinding,
    MyMenuItem,
    MyContextMenuService,
    etc
)
Honey answered 27/11, 2014 at 1:21 Comment(1)
This was the only working solution here. You may also put the .dll's to any other folder as long as it is added to sys.path with sys.path.append(dll_folder).Jadda
M
5

Did you try clr.FindAssembly?

import clr
import sys
assemblydir = r"C:\pyfornet_test"
assemblypath = r"C:\pyfornet_test\DotNet4Class.dll"
sys.path.append(assemblydir)
clr.FindAssembly(assemblypath)

I don't know why it works, but this code works on my computer (Python 2.7, .NET4)

Middleoftheroad answered 25/6, 2015 at 9:28 Comment(1)
It doens't wrok for meFluting
J
5

Checklist

  1. The folder(s) containing the DLL(s) is/are added to sys.path before loading. You may append, or sys.path.insert(0, dll_folder) to put it first on the list.
  2. You call clr.AddReference('my_dll') without the dll extension (for my_dll.dll), after adding the folder to sys.path
  3. The DLL Target Architecture is the same as the CPython version bitness. That is, if Architecture is x64, use 64-bit python, and if Architecture is x86, use 32-bit python. (instructions for this below)
  4. Windows has not blocked the dll(s) involved. You may check this from "Properties" -> "General" and see if there is an empty checkbox saying "Unblock". You may unblock multiple files in Powershell with dir -Path . -Recurse | Unblock-File. The Recurse is optional (will also unblock everything in subfolders).

How to check target Architecture for DLL?

  • I Used ILSpy (free and open source) -> Open DLL -> Check the output. Below example output.

ILSpy example

Jadda answered 13/4, 2020 at 18:56 Comment(5)
Thanks for the checklist @np8. I still can't get the assembly loaded. I got a x64 C# dll. I'm be able to load this dll within a C# project on Visual Studio. Running the code ` print(clr.FindAssembly(Myassembly))` will point to the correct folder where the dll is located. Running clr.AddReference(Myassembly) will lead to the following error. System.IO.FileNotFoundException: Unable to find assembly 'Myassembly'. Any ideas?Expiatory
How does your sys.path look just before you call clr.Addreference(Myassembly)? Does it contain a folder which contains the Myassembly DLL?Jadda
The first entry will be the path to the folder where Myassembly is located. I added it by the following comand sys.path.insert(0, assemblydir), where assemblydir is the path to Myassembly. So I think, the clr package is able to find Myassembly. Therefore the command clr.FindAssembly(Myassembly) comes up with the correct path to Myassembly. The function clr.FindAssembly(Myassembly) will fail if I don't add the folder to the sys.path. Could it be possible that another application loaded the dll and it is therefore be blocked? Have not yet tried to load the dll by ctypes.Expiatory
Did you try to run the tests found in the Troubleshooting guide? I.e. Does pythonnet work with other DLL's such as the Python.EmbeddingTest.dll?Jadda
@pn8, you pointed me the right way. I accidentally thought I'm using a .Net dll. In Fact it is a ActiveX dll. Therefore I use the package import win32com.client to run this ActiveX object. What I used within python was the following code. dll_ref = System.Reflection.Assembly.LoadFile(Myassembly) I got this from here link. Then I was able to find out that it is not a valid .Net dll. This might become a new point on your checklist.Expiatory
G
0

What worked for me was to Unblock the dll file.

if u download the dll file or took it from different computer it might be blocked. So unblocked solved the issue for me.

To unblock right click on the properties if the dll file and check the Unblock box at the bottom

Garfield answered 22/7, 2021 at 9:51 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.