Applying bindingRedirect config to pythonnet - c#

I have an application that relies on NuGet's <bindingRedirect> feature to ensure a single version of log4net.dll. Binding redirects are automatically added to the applications app.config file.
I'd like to load that application's assemblies into Python and call into its code, but because the binding redirects are application-specific, they're not being picked up by Pythonnet and the assembly fails to load:
LOG: Post-policy reference: log4net, Version=1.2.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a
[...snip...]
LOG: Assembly Name is: log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a
WRN: Comparing the assembly name resulted in the mismatch: Major Version
Can I get pythonnet to refer to my application's app.config and use the <bindingRedirect> found there? Or can I apply a binding redirect after startup, without needing an app.config?

Here is how to enable app.config with pythonnet when using .NET assemblies from CPython:
Place python.exe.config file next python.exe with the following configuration for detection later:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="customAppSettingsGroup">
<section name="customAppSettings" type="System.Configuration.AppSettingsSection, System.Configuration" />
</sectionGroup>
</configSections>
<customAppSettingsGroup>
<customAppSettings>
<add key="Debugger" value="True"/>
</customAppSettings>
</customAppSettingsGroup>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
</startup>
</configuration>
Generate .NET assembly with the following code for testing and reading app.config settings:
using System;
using System.Collections.Specialized;
using System.Configuration;
namespace dotnet20
{
public class Class1
{
public Class1()
{
NameValueCollection settings =
ConfigurationManager.GetSection("customAppSettingsGroup/customAppSettings") as NameValueCollection;
if (settings != null)
{
foreach (string key in settings.AllKeys)
{
if ((key == "Debugger") && (settings[key] == "True"))
{
Console.WriteLine("Detected debugger mode");
}
}
}
}
}
}
Now test that pythonnet is able to detect these custom settings from app.config:
python
Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import clr
>>> import sys
>>> sys.path.append(r"C:\pythonnet\dotnet2.0\bin\Debug")
>>> clr.AddReference("dotnet2.0")
<System.Reflection.RuntimeAssembly object at 0x000001A51626D630>
>>> from dotnet20 import Class1
>>> Class1()
Detected debugger mode
<dotnet20.Class1 object at 0x000001A51626D6A0>
>>>

I have got into similar problem using Pythonnet with .net dLLs.
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' or one of its dependencies. The system cannot find the file specified.
I didn't have Version 3.1.0.0 of Microsoft.Extensions.DependencyInjection.Abstractions and hence the error. My .net project has app.config file which was pointing to a newer version of this dependency ( 3.1.5.0) [ bindingRedirect ]
The solution was to use this app.config file from .net project, rename it to python.exe.config and put it in the same folder where python.exe is. I am not sure if this is the best solution but i have looked in to a bunch of other solutions and this only seems to be working.

You can use pyinstaller (to install with pip: pip install pyintaller see project page) to create a single executable file and place the config file in the same folder.
be able to work with the app.exe.config files on a per project basis.
pyinstaller --onefile script.py
this will create a dist folder inside your current working directory with an exe file (script.exe) and there you can place your script.exe.config file which will parse upon running script.exe

Related

ASPCONFIG: Could not load file or assembly 'Microsoft.VisualStudio.QualityTools.UnitTestFramework, or one of its dependencies

My team is moving on project to to Azure DevOps. While the project is running correctly locally, it failed to build two of our Web Sites in DevOps
The error message:
##[error]MyProject\MyWebServices\web.config(59,0): Error ASPCONFIG: Could not load file or assembly
'Microsoft.VisualStudio.QualityTools.UnitTestFramework,
Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or
one of its dependencies. The system cannot find the file specified.
The compiler command:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_compiler.exe
-v /MyWebServices -p MyWebServices\ -u -f PrecompiledWeb\MyWebServices\
The Web.Config had the following line:
<compilation debug="true" targetFramework="4.5">
<assemblies>
<add assembly="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
</assemblies>
</compilation>
I have read this post and this post and the solution provided are not working for me.It was not a type mismatched because I have tried both x84 and x64 compilation and they are both failing for me.
Any idea how to solve this problem?
If your project depends on build environment, we suggest that you use self-hosted agents, which give you more control to install dependent software needed for your builds and deployments. If the project is running correctly locally, you should get the same result using self-hosted agents which will build on your local machine.
In addition, if you prefer to use Microsoft-hosted agents, please make sure that it is the same build environment as your local machine. You can see the installed software for each hosted agent by choosing the Included Software link in the table.
BTW, you could set pipeline variable system.debug to true, and then queue a new build to get debug logs, so you can review it to get detailed build information. See: Troubleshoot pipeline runs for details.

Unable to load DLL 'curand64_80'

This is my first time trying to run the Alea TK MNIST example on my machine.
I installed CUDA 8 and everything in accordance with http://www.aleagpu.com/release/3_0_2/doc/installation.html
However running it I always get this error: Unable to load DLL 'curand64_80': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Even though I can clearly see the curand64_80.dll in C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin
I've set the configuration as such (app.config):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="aleaSettings" type="Alea.Settings, Alea"/>
</configSections>
<aleaSettings>
<cuBLAS version="8.0"/>
<cuRAND version="8.0"/>
</aleaSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>
This is the full exception stack trace:
at Alea.DynamicInterop.curandCreateGenerator.Invoke(IntPtr , RngType )
at A.cdbbf7f52ce1317681b2fa10b7329e78e.-ctor#386-309.Invoke(Unit _arg3)
at Alea.cuRAND.Generator..ctor(FSharpOption`1 cc2af9506f3fc494fecea785eae58ff3b, FSharpOption`1 cdd5e91d5c509dec430918468c49a7937, RngType c23e4321fb7f1de7409a3cd12e2cd5890)
at (FSharpOption`1 , FSharpOption`1 , RngType )
at AleaTK.GpuContext.CreateRandomGenerator(PseudoRandomType type)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at AleaTK.ExprImpl.PseudoRandomExpr`1.Execute(Assignment assignment, ILValue`1 output)
at AleaTK.LExpr`1.Execute(Assignment assignment)
at System.Threading.Tasks.Task.Execute()
What am I missing and how can I run the sample successfully?
Alea GPU 3.0.2 is looking for CUDA toolkit 7.5 by default. You seem to use CUDA toolkit 8.0. You have to configure Alea GPU accordingly. Refer to the documentation for details how to config the CUDA tookit version. Also make sure that you build and run 64 bit because several CUDA libraries are only available in 64bit. HTH.
Update the PATH environment variable to include C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin
I assumed that the CUDA installation would update my PATH environment variable, but it didn't

Mono: runtime error: v4.0.30319

I have a big problem with Mono; constantly receiving this error message.
WARNING: The runtime version Supported by This application is unavailable. Using default runtime: v4.0.30319
I have reinstalled the server three times already, but new installs unfortunately always have the same problem.
OS: Debian 7 mini
Mono: full instaled (mono-complet up to date)
PROCON: 1.4.0.6
Link: PROCON usage on Debian 7
If the application starts normally and you only want to suppress the warning, there are two options:
Configuration file
Add the configuration file to the directory where the binary is located, with the name <binary-name>.config, e.g. for application.exe use application.exe.config.
The contents of the file should be as following. Of course, the comment is optional.
<?xml version="1.0" encoding="utf-8"?>
<!-- Add this file to the legacy .NET application folder to prevent:
WARNING: The runtime version supported by this application is unavailable. -->
<configuration>
<startup>
<supportedRuntime version="v2.0.50727"/>
<supportedRuntime version="v4.0"/>
</startup>
</configuration>
Sources
http://do-the-right-things.blogspot.cz/2017/05/the-way-to-suppress-monos-warning.html
https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/#application-configuration-files
Command line
Specify the runtime manually when launching the application.
mono --runtime=v4.0 application.exe
Sources
https://linux.die.net/man/1/mono
Mono on MacOSX - "The runtime version supported by this application is unavailable." v4.5
If you use a dissembler to check the assemblies you should see which CLR version they were built against. My guess is that they were built against 2.0.
Mono 4 removes the old 2.0 CLR and 4.0 CLR (in fact 4.5 profile) becomes the default and the only. So this is simply a warning, not an error.

C# Dynamic Data Linq To SQL website assembly loading

I am using visual studio 2010 ultimate. I have got the following error when I try to import a dynamic data linq to sql website project on my computer:
------ Rebuild All started: Project: C:...\TestVersion99Website\, Configuration: Debug Any CPU ------ Validating Web Site Building
directory '/TestVersion99Website/App_Code/'. Building directory
'/TestVersion99Website/DynamicData/Content/'. Building directory
'/TestVersion99Website/DynamicData/FieldTemplates/'.
C:\Users\Test\Documents\Visual Studio
2010\WebSites\TestVersion99Website\DynamicData\FieldTemplates\MultilineText_Edit.ascx(7):
Build (web): Could not load file or assembly 'System.Web.DynamicData,
Version=99.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or
one of its dependencies. The system cannot find the file specified.
... C:\Users\Test\Documents\Visual Studio
2010\WebSites\TestVersion99Website\DynamicData\FieldTemplates\Text_Edit.ascx(7):
Build (web): Could not load file or assembly 'System.Web.DynamicData,
Version=99.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or
one of its dependencies. The system cannot find the file specified.
Validation Complete
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
The website was written using .net 3.5 sp1 framework. The System.Web.DynamicData assembly was from DynamicData 4 preview project from codeplex.
To identify the error, I have created a new dynamic data linq to sql website project using .net 3.5 framework. Once the website is built, I removed the reference to "System.Web.Dynamicdata 3.5.0.0". I created a new Bin folder, and copied the assembly "Microsoft.Web.Extensions 99.0.0.0, System.ComponentModel.DataAnnotations 99.0.0.0, System.Web.DynamicData 99.0.0.0" into the Bin folder. I then made sure that in web.config the assembly versions are changed to 99.0.0.0. However, When I tried to build the solution, I still had the same error messages. I have no idea why this is happening and am really really very frustrated.
Check for any bindingRedirect you have in your web.config.
<dependentAssembly>
<assemblyIdentity name="System.Web.DynamicData" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="3.5.0.0" newVersion="99.0.0"/>
</dependentAssembly>

Failed obtaining configuration for Common.Logging from configuration section 'common/logging'

I'm trying to configure a console application with the following logging assemblies:
Common.Logging.dll (2.1.0.0)
Common.Logging.Log4Net1211.dll (2.1.0.0)
log4net.dll (1.2.11.0)
If the logger gets configured programmatically then everything works fine:
NameValueCollection properties = new NameValueCollection(); properties["showDateTime"] = "true";
Common.Logging.LogManager.Adapter = new Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter(properties);
But if I try to launch it using the following configuration file, it blows up:
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</sectionGroup>
</configSections>
<common>
<logging>
<factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net">
<arg key="configType" value="FILE-WATCH"/>
<arg key="configFile" value="~/Log4NET.xml"/>
</factoryAdapter>
</logging>
</common>
</configuration>
These are the relevant error messages:
{"Unable to cast object of type 'System.Configuration.DefaultSection' to type 'System.Configuration.AppSettingsSection'."}
{"Failed obtaining configuration for Common.Logging from configuration section 'common/logging'."}
It seems to being unable to parse my configuration file, does anyone know what the correct format should be or is it something else that's wrong? I created my configuration file using the official documentation.
I was having this (or related) issue as well and after half a day of error hunting and debugging I narrowed it down to a configuration problem.
The exception was the same as the OP and the inner exception a few level inside of it was failing to find Common.Logging.Log4Net (FileNotFoundException).
It seems that for the Common.Logging.Log4Net1211 NuGet package, they have renamed the assemblyname to be Common.Logging.Log4Net1211 instead of simply Common.Logging.Log4Net. This means in your app.config you need to refer to this new assembly name:
<factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4net1211">
Here's my entire common/logging section of app.config for reference:
<common>
<logging>
<!-- Notice that it's Log4net1211 -->
<factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4net1211">
<arg key="configType" value="FILE-WATCH" />
<arg key="configFile" value="~/Log4Net-MAIN.config" />
</factoryAdapter>
</logging>
</common>
There are two problems with your application (the one I downloaded):
Your configSections in app.config looks like this:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</sectionGroup>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
Notice that the log4net-section is declared twice? Remove the first one.
After removing the first log4net-section, I get the following:
Could not load file or assembly 'log4net, Version=1.2.11.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
I downloaded log4net 1.2.11.0 from the log4net website, unzipped it, unblocked the dll and replaced the log4net in your example and it seems to work.
I'm using
Common.Logging v3.3.1.0
with
Common.Logging.Log4Net1213 v3.3.1.0
in ASP.NET Web API v5, which throws exception
"parent configuration sections are not allowed"
Exception is thrown from Common.Logging.ConfigurationSectionHandler.Create method
In order to make this work, I had to grammatically configure the adapter
var properties = new Common.Logging.Configuration.NameValueCollection();
properties["configType"] = "INLINE";
Common.Logging.LogManager.Adapter = new Log4NetLoggerFactoryAdapter(properties);
I still have to figure out why IIS/Express calls the Create method twice, which is causing the exception to be thrown inside the if condition, but at least the pressure is off for now.
I got it working by installing a missing package
Install-Package Common.Logging.Log4Net1211
Although this is an old question, I had this issue a few weeks and none of the current answers seemed to remedy it. It seemed my configuration was correct as I had many other applications using near identical configuration with no issue. After quite a bit of debugging and running through stacktraces, I finally found the issue.
Notice that in IIS, I have the API application hosted under another application. In this case both the CAMP application and the API application under it are both using Common.Logging. Because of this, both web.config files get loaded, Common.Logging reads CAMP's configuration, then it sees that API has configuration and tries to read that as well, sees the Common.Logging section and throws up because it already read that from the CAMP application.
In the end the solution was to move the API out from under the CAMP application in IIS. A bit of an obsucre edge case, but perhaps someone else might face this issue some day.
Can you try with Common.Logging.dll version 2.1.1.0 instead.
You can download and compare the source of the two versions yourself, but as far as I can see the only difference between 2.1.0.0 and 2.1.1.0 is a change relating to reading the configuration settings in order to workaround a Framework 4.0 bug. The description of the bug (see http://support.microsoft.com/kb/2580188) refers to running from a network share which I am not running from a network, yet a test app using 2.1.0.0 generates the same error as you are getting whereas 2.1.1.0 doesn't.
If you are using another library that expects version 2.1.0.0 of common.logging.dll, then you should be able to using an assembly redirect to use 2.1.1.0 instead.
PS
Not sure whether it is relevant, but I left the name of the dll as Common.Logging.Log4Net121.dll and modified the app.config instead
I found that it was due to the Common.Logging.Log4Net1211 NuGet package retrieveing an older version of Common.Logging. Check for NuGet updates to Common.Logging and if you find one download it and try again.
If your log4net is 2.0.6 or above, it may be convenient to use Common.Logging.Log4Net.Universal package.

Categories

Resources