Problem with 32-bit COM component from 64-bit application. (TYPE_E_CANTLOADLIBRARY) - com

I have a created a dummy application for testing purposes which is a 64-bit console application, which creates an instance of a 32-bit COM application. It is a third party application called Laserforms.
static void Main(string[] args)
{
LFM32.Application application;
try
{
application = new LFM32.Application();
Console.WriteLine("Success!");
application.Quit();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
finally
{
Console.Read();
}
}
Now, this works perfectly on my machine, but when I deploy it to another machine, which has Laserform installed as well I am getting the below error message.
{System.InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to interface type 'LFM32.Application'.
This operation failed because the QueryInterface call on the COM component for the interface with IID '{6688DD46-3DA3-4FEC-8A1F-54E1453DCC77}'
failed due to the following error: Error loading type library/DLL. (Exception from HRESULT: 0x80029C4A (TYPE_E_CANTLOADLIBRARY)).}
I have go one through the registry of both and can't see any differences, what else could I be doing wrong?
UPDATE:
So I ran TlbImp on the .tlb file to create a DLL I could reference in my .NET application. This created a couple of extra DLLs and some warnings around Iunknown and some invalid types. I then ran Regasm (from Framework and Framework64) on this and the other DLLs it created but I am still seeing the exact same error.

Related

Python.Net PythonEngine.Initialize() crashes application without throwing exception

My application (C#, VS2017) previously targeted Python 3.5.1. I have updated the system to Python 3.7.1 and have this is causing PythonEngine.Initialize() to crash the application without throwing an exception.
One internet suggestion was to set the Python env in VS, however this causes VS2017 to close when opening Python/environments. I switched to VS2019 and encountered the same issue with the stripped down code here:
using System.Windows.Forms;
using Python.Runtime;
namespace WindowsFormsApp3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
try
{
PythonEngine.Initialize();
}
catch (Exception e)
{
string ex = e.ToString();
}
}
}
}
Python.Net was installed successfully using:
pip install pythonnet
UPDATE Dec 2022
There are 2 optional environment strings you can use to locate the python dll.
PYTHONNET_PYDLL explicitly set the dll name
PYTHONNET_PYVER explicitly set just the version string part of the dll name
Compiling with WINDOWS, OSX or LINUX defined is not required anymore
Here's my PythonNet init function.
Note that running "pip install pythonnet" only installs the ability to load & use CLR types & assemblies from Python. To embed PythonNet in a C# app, you actually don't need to install pythonnet on the Python side.
This function uses some globals set at startup.
Program.PythonHome -- points to the Python root folder I'm using
Program.ScriptsDir -- my own app python scripts dir
Program.ApplicationName -- just my own app name
I also call PythonEngine.BeginAllowThreads(); as I'm calling from multiple threads.
public static void InitPython(Microsoft.Extensions.Logging.ILogger logger)
{
string py_home = Program.PythonHome;
string py_path = $"{py_home};";
// will be different on linux/mac
string[] py_paths = {"DLLs", "lib", "lib/site-packages", "lib/site-packages/win32"
, "lib/site-packages/win32/lib", "lib/site-packages/Pythonwin" };
foreach (string p in py_paths)
{
py_path += $"{py_home}/{p};";
}
try
{
PythonEngine.PythonPath = $"{Program.ScriptsDir};{py_path}";
PythonEngine.PythonHome = Program.PythonHome;
PythonEngine.ProgramName = Program.ApplicationName;
PythonEngine.Initialize();
PythonEngine.BeginAllowThreads();
logger.LogInformation("Python Version: {v}, {dll}", PythonEngine.Version.Trim(), Runtime.PythonDLL);
logger.LogInformation("Python Home: {home}", PythonEngine.PythonHome);
logger.LogInformation("Python Path: {path}", PythonEngine.PythonPath);
}
catch (System.TypeInitializationException e)
{
throw new Exception($"FATAL, Unable to load Python, dll={Runtime.PythonDLL}", e);
}
catch (Exception e)
{
throw new Exception($"Python initialization Exception, {e.Message}", e);
}
}

System.Security.Permissions missing when invoking JsonConvert.DeserializeObject in .NET Core 3.0

I have generated the Csharp client for WebAPICore using the OpenAPI generator.
I am getting the local response as 200 with ResponseStatus:OK
But while type casting the response as shown below:
try {
return JsonConvert.DeserializeObject(response.Content, type, serializerSettings);
} catch (Exception e) {
throw new ApiException(500, e.Message);
}
AT return JsonConvert.DeserializeObject(response.Content, type, serializerSettings);. It is having the following issue:
Could not load file or assembly 'System.Security.Permissions, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.
I have tried installing the NuGet Package with version: 4.0.3.0 and added the reference to Project, but still facing the same.

ReflectionTypeLoadException in ASP.NET Core MVC application

I'm running into a problem running an ASP.NET Core 1.0 application targeting .NET Framework 4.6. The problem didn't occur until we tried to run the application on a server running Windows Server 2016. The app is hosted in IIS and I have the .NET Core 1.0 Windows Hosting Bundle installed on the server.
Upon loading the site a 500 error is returned and this is written to the Logs:
An unhandled exception has occurred: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information. (fc7986d0)
System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
Researching this it appears to relate to a missing dll or mismatched version, and that I should look at the LoaderExceptions property to get more info, but I'm not sure how to do that in this instance. The log entry is created just from setting up the loggerFactory in the Configure() method of Startup.cs.
I tried adding an IExceptionFilter ActionFilter implementation and reading the LoaderExceptions property if the exception is of type ReflectionTypeLoadException, but it doesn't get hit when ran on the server.
Is there a way to drill down into the Exception to read the LoaderExceptions property (in a production environment, there is no error when running in Visual Studio so debugging didn't help), or else another way to troubleshoot the original error to determine what is wrong with the server setup?
Instead of using IExceptionFilter, I wrote my own Middleware for catching this sort of exception and was able to log each exception from the LoaderExceptions property and determine what my problem is. Here is what I added to log the LoaderExceptions:
public class ExceptionCatchMiddleware
{
private readonly RequestDelegate _delegate;
private readonly ILogger _logger;
public ExceptionCatchMiddleware(RequestDelegate requestDelegate, ILogger<ExceptionCatchMiddleware> logger)
{
_delegate = requestDelegate;
_logger = logger;
}
public async Task Invoke(HttpContext context)
{
try
{
await _delegate(context);
}
catch (ReflectionTypeLoadException e)
{
foreach (Exception ex in e.LoaderExceptions)
{
_logger.LogCritical(ex.Message + Environment.NewLine + ex.StackTrace);
}
}
}
}
And then I just needed to add the Middleware to the Configure() method in Startup.cs:
app.UseMiddleware<ExceptionCatchMiddleware>();
In my case it was a missing dll that wasn't included in the project but since it was in my dev machine's GAC it ran there just fine.

The type initializer for 'NHibernate.Cfg.Configuration' threw an exception

After upgrading from nhibernate 1.0.4.0 to nhibernate 3.3 im encountering the following error when I try to run "Configuration cfg = new Configuration();"
System.TypeInitializationException was caught
Message="The type initializer for 'NHibernate.Cfg.Configuration' threw an exception."
Source="NHibernate"
TypeName="NHibernate.Cfg.Configuration"
StackTrace:
at NHibernate.Cfg.Configuration..ctor()
at KEH.Web.Data.NHibernateUtil..cctor() in F:\Projects\KEH nHibernate\KEHWeb\Data\Data\NHibernateUtil.cs:line 24
InnerException: System.NotSupportedException
Message="The invoked member is not supported in a dynamic assembly."
Source="mscorlib"
StackTrace:
at System.Reflection.Emit.AssemblyBuilder.get_Location()
at log4net.Util.SystemInfo.AssemblyLocationInfo(Assembly myAssembly)
at log4net.Core.DefaultRepositorySelector.GetInfoForAssembly(Assembly assembly, String& repositoryName, Type& repositoryType)
at log4net.Core.DefaultRepositorySelector.CreateRepository(Assembly repositoryAssembly, Type repositoryType, String repositoryName, Boolean readAssemblyAttributes)
at log4net.Core.DefaultRepositorySelector.CreateRepository(Assembly repositoryAssembly, Type repositoryType)
at log4net.Core.DefaultRepositorySelector.GetRepository(Assembly repositoryAssembly)
at log4net.Core.LoggerManager.GetLogger(Assembly repositoryAssembly, String name)
at log4net.LogManager.GetLogger(Assembly repositoryAssembly, String name)
at log4net.LogManager.GetLogger(Type type)
at lambda_method(ExecutionScope , Type )
at NHibernate.Log4NetLoggerFactory.LoggerFor(Type type)
at NHibernate.LoggerProvider.LoggerFor(Type type)
at NHibernate.Cfg.Configuration..cctor()
InnerException:
Any help would be greatly appreciated.
The NHibernateUtil class code is as follows :
public class NHibernateUtil
{
private static readonly Configuration cfg;
private static readonly ISessionFactory sessionFactory;
private static readonly ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
static NHibernateUtil()
{
try
{
logger.Debug("Before Initializing NHibernate");
cfg = new Configuration();
cfg.AddAssembly("KEH.Web.Data");
sessionFactory = cfg.BuildSessionFactory();
logger.Debug("Initialized NHibernate");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public static ISession OpenSession()
{
logger.Debug("Before Getting Connection");
return sessionFactory.OpenSession();
}
}
I had the same problem.
The actual reason was i used a library that used old version of log4net.
NHibernate tries to use it if find.
So i had to force it to use (or actually not use) other logger by adding such line:
LoggerProvider.SetLoggersFactory(new NoLoggingLoggerFactory());
Not sure why it's not working, but I'd just replace
cfg.AddAssembly("KEH.Web.Data");
with
cfg.AddAssembly(typeof(Entity).Assembly);
where Entity is some class that exists in the assembly of your mapping files.
For the benefit of others who might find this question via Google:
For us, this error was a red-herring. Our app ran fine until we deployed a new component AND it would fail (in an unknown way) AND IIS would recycle the app pool. The problem was an HTML to JPG component we were using was erroring somehow and causing all of our w3wp.exe worker processes to consume maximum CPU. When the app pool was recycled via IIS, the entire site would go down and NHibernate would throw this error continuously until an iisreset. Before the recycle, the site would still be very responsive even with the CPU load.
While we still don't know how the component was failing or why it was cascading to problems with NHibernate initializing, the point is it was a red-herring. Be sure to watch for this error "suddenly" occurring shortly after a new deployment, and keep logs of your CPU utilization so it can help spot when trouble is brewing. Finally, if the downtime is happening near the same time every day, it's probably an automatic IIS app pool recycle, and that should be another clue that something is bugging out your application and surfacing during the recycle.
Ultimately, we disabled the HTML to JPG component until a workaround can be found and our up-time sprung back to 100%.
Hope this helps someone.

Could not load middleware layer 'com.sap.mw.jco.rfc.MiddlewareRFC'

I'm using Sap Jco to connect to SAP database with the front end being Java(JSF), When I connect to SAP with:
try {
mConnection =JCO.createClient("400", // SAP client
"c3026902", // userid
"********", // password
"EN", // language
"iwdf5020", // host name
"00"); // system number
mConnection.connect();
}
catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
Problem I'm facing is when run the application for the first time, data is displayed but when I re-run it says "Could not load middleware layer 'com.sap.mw.jco.rfc.MiddlewareRFC' "
Can any one help me in resolving the issue?????
This sounds like the API cannot load the native driver files.
The SAP Java Connector consists of a native runtime part, that does the actuall communication and a Java API that wraps this functionality with a java api.
The Java API is inside the sapjco.jar and the native drivers are e.g on windows inside librfc32.dll and sapjcorfc.dll.
Place these dll's into your system path (e.g. windows: C:\WiNDOWS\system32) and it should run.
Cheers
Sebastian
Are your DLLs located in the Windows system32 folder? If so, are you probably using the wrong architecture? (x64 DLL on 32 bit or vice versa)
Also, are the DLLs the same version as the java api? If you have SAP GUI installed there could be older DLLs around.
Defining SAP connection:
For the Version 3,0 of the sapjco library there exists plenty of useful information. To create a connection following the instructions in:
http://www.browseye.com/linkShare.html?url=http://help.sap.com/saphelp_nwpi711/helpdata/en/46/fb807cc7b46c30e10000000a1553f7/content.htm?bwsCriterion=%22Setting%20Up%20Connection%22&bwsMatch=1&bwsCriterion=%22Setting%20Up%20Connection%22&bwsMatch=1
There are a few thing that you should take into account:
Place the dll file in the same place that the jar.
The dll must be the right version for your operating system and architecture otherwise you will get a native library error.
Example of code to create a connection to the server.
public class StepByStepClient
{
static String DESTINATION_NAME1 = "ABAP_AS_WITHOUT_POOL";
static String DESTINATION_NAME2 = "ABAP_AS_WITH_POOL";
static
{
Properties connectProperties = new Properties();
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "ls4065");
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "85");
connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "800");
connectProperties.setProperty(DestinationDataProvider.JCO_USER, "homofarber");
connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "laska");
connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "en");
createDestinationDataFile(DESTINATION_NAME1, connectProperties);
connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, "3");
connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, "10");
createDestinationDataFile(DESTINATION_NAME2, connectProperties);
}
static void createDestinationDataFile(String destinationName, Properties connectProperties)
{
File destCfg = new File(destinationName+".jcoDestination");
try
{
FileOutputStream fos = new FileOutputStream(destCfg, false);
connectProperties.store(fos, "for tests only !");
fos.close();
}
catch (Exception e)
{
throw new RuntimeException("Unable to create the destination files", e);
}
}
public static void step1Connect() throws JCoException
{
JCoDestination destination = JCoDestinationManager.getDestination(DESTINATION_NAME1);
System.out.println("Attributes:");
System.out.println(destination.getAttributes());
System.out.println();
}
}
In SAPJco 3.0 connections are build from the info contained in a “Destination”.
The documentation example use a properties file to save the “Destination”. However it is a non-secure way to keep connection info. As is indicated on the documentation in the hightlighted paragraph you can see on next link.
http://help.sap.com/saphelp_nwpi711/helpdata/en/48/5fb9f9b523501ee10000000a421937/content.htm?bwsCriterion=%22In%20practice%20you%20should%20avoid%20this%20for%20security%20reasons.%22&bwsMatch=1
You can keep connection info on a database or any other storage system if you create a custom “DestinationDataProvider” In the Examples provided with the SAPJco library there is an example of how to create a custom DestinationDataProvider.