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
Impossible to register an instance of activeX object #578
Comments
Can you post the full stack trace? |
There it is:
|
Under the covers, Simple Injector uses the This means that, in your case, the following statement returns false: typeof(InteropFactoryX).IsAssignableFrom(interopFactory.GetType()) I'm unsure how to actually fix this. |
Yes, your are right typeof(InteropFactoryX).IsAssignableFrom(interopFactory.GetType()) == false
I will search if in can do some tricks on my object to force |
Perhaps the internal validation can be changed, but I'm unsure how to effectively detect that the proxy object is castable to the given base type. A possible workaround would be to create create a class that wraps the public class InteropWrapper : InteropFactoryX
{
public InteropFactoryX Instance { get; set; }
// Implement all methods as forwards.
void InteropFactoryX.Method1() => this.Instance.Method1();
}
container.RegisterInstance<InteropFactoryX>(new InteropWrapper { Instance = interopFactory }); |
Ok, so I found some solution for managing ComObject. if(obj.GetType().IsCOMObject)
{
string realComObjectType = Microsoft.VisualBasic.Information.TypeName(obj);
if( realComObjectType == TypeInTemplate)
// obj can be added
} The second is more dirty. Just the way to get the type name is different. public static string GetComObjectRealTypeName(object comObj)
{
if (comObj == null)
return String.Empty;
if (!Marshal.IsComObject(comObj))
//The specified object is not a COM object
return String.Empty;
IDispatch dispatch = comObj as IDispatch;
if (dispatch == null)
//The specified COM object doesn't support getting type information
return String.Empty;
System.Runtime.InteropServices.ComTypes.ITypeInfo typeInfo = null;
try
{
try
{
// obtain the ITypeInfo interface from the object
dispatch.GetTypeInfo(0, 0, out typeInfo);
}
catch (Exception ex)
{
//Cannot get the ITypeInfo interface for the specified COM object
return String.Empty;
}
string typeName = "";
string documentation, helpFile;
int helpContext = -1;
try
{
//retrieves the documentation string for the specified type description
typeInfo.GetDocumentation(-1, out typeName, out documentation,
out helpContext, out helpFile);
}
catch (Exception ex)
{
// Cannot extract ITypeInfo information
return String.Empty;
}
return typeName;
}
catch (Exception ex)
{
// Unexpected error
return String.Empty;
}
finally
{
if (typeInfo != null) Marshal.ReleaseComObject(typeInfo);
}
}
/// <summary>
/// Exposes objects, methods and properties to programming tools and other
/// applications that support Automation.
/// </summary>
[ComImport()]
[Guid("00020400-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IDispatch
{
[PreserveSig]
int GetTypeInfoCount(out int Count);
[PreserveSig]
int GetTypeInfo(
[MarshalAs(UnmanagedType.U4)] int iTInfo,
[MarshalAs(UnmanagedType.U4)] int lcid,
out System.Runtime.InteropServices.ComTypes.ITypeInfo typeInfo);
[PreserveSig]
int GetIDsOfNames(
ref Guid riid,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)]
string[] rgsNames,
int cNames,
int lcid,
[MarshalAs(UnmanagedType.LPArray)] int[] rgDispId);
[PreserveSig]
int Invoke(
int dispIdMember,
ref Guid riid,
uint lcid,
ushort wFlags,
ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams,
out object pVarResult,
ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo,
IntPtr[] pArgErr);
} ps: your solution is very hard to use and maintain. I have somethings like 50 Com objects to store is SimpleInjector 😄 |
Also try the following: container.RegisterSingleton<InteropFactoryX>(() => interopFactory); That will circumvent the |
This is working but there is an exception when I call
Stacktrace:
And if I drop the |
Do you have simple example for me that I can use to reproduce the issue locally, and possibly include as a unit test? |
I thinks the problem should be the same we Excel Com object for example. |
Ideally, I would use an example that doesn't require an out-of-process object to be created, since the unit tests must be able to run on AppFayor—not just on a developer's machine. |
You can try to get an activeX object on internet explorer. |
Ok, so you can found in the archive a minimal example it's pretty simple, just a console app with ref on The code is: using SimpleInjector;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
try
{
Container c = new Container();
SHDocVw.InternetExplorer IE = new SHDocVw.InternetExplorer();
c.RegisterInstance(IE);
c.Verify();
var test = c.GetInstance<SHDocVw.InternetExplorer>();
test.ToolBar = 0;
}
catch(Exception e)
{
throw e;
}
}
}
} |
Hi, |
Hi @Ducatel, This feature is currently on the backlog, but its still uncertain whether we will add it to the v5.0 release. Don't get your hopes up and workaround accordingly. |
That what I do, but I have something like 200 objects wrapped and this make my code quite ugly. |
I just pushed my changes that fix this bug. Many thanks to your provided |
It's so cool, thanks for the fix ;) |
Do note thatonly manually constructed COM objects will be supported. You can't let Simple Injector create your COM object. Would that be a problem? |
I'm happy to announce Simple Injector v5 has been released, which now allows registration of COM objects. |
Youpi , I will test that soon :p |
New issue related to COM objects was reported here #986. |
Hi,
I'm trying to register an instance of an activeX (ATL/COM object) but the register fail.
When I call
RegisterInstance
, an exception was throw:A Sample which produce this error:
So why I have this error ? There is somethings special to do when we try to store activeX object ?
Thanks in advance for your help
Ps: SimpleInjector version 4.3.0
Ps2: When I wrap the interopFactory in a class, it's working.
The text was updated successfully, but these errors were encountered: