Question:
I have to work (in VB.NET) with an application (Aperture)'s OLE automation via COM-Wrapper.
Currently, I switch off option strict, and do it like this (using late-binding):
Dim m_Aperture As Object = CreateObject("Aperture.Application")
Dim m_Project As Object = m_Aperture.Project
You see the problem, everything is an object, no intellisense, etc.
Very bad.
Since I want to get intellisense and and compile-time checking to work, I tried to automatically create a COM-wrapper like this:
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\TlbImp.exe" OEAPP.TLB /out:Aperture.dll
So far worked splendidly, it created the wrapper, I can use intellisense on it (return types are all of type dynamic though).
So I tried to rewrite just the above sample code (now in C#):
First attempt was:
Aperture.OEAppClass app = new Aperture.OEAppClass();
But I got this compiler error:
Interop-Type Aperture.OEAppClass cannot be embedded. Use interface instead.
So i tried to do it via interface:
Aperture.OEApp Ap = (Aperture.OEApp)Microsoft.VisualBasic.Interaction.CreateObject("Aperture.Application");
That got me an exception at runtime
InvalidCastException
"System.__ComObject" cannot be converted into interface type "Aperture.OEApp".
0x80010105 (RPC_E_SERVERFAULT)).
So I tried to figure out the interface type using
dynamic Ap2 = Microsoft.VisualBasic.Interaction.CreateObject("Aperture.Application");
and object-inspector.
I found out the interface is actually of type Aperture._IOEApp.
So I used
Aperture._IOEApp Ap = (Aperture._IOEApp)Microsoft.VisualBasic.Interaction.CreateObject("Aperture.Application");
But now I get
InvalidCastException
"System.__ComObject" cannot be converted into interface type "Aperture._IOEApp".
0x80010105 (RPC_E_SERVERFAULT)).
Now I don't know what the problem could be anymore.
Can anybody tell me what I do wrong ?
Or how this is supposed to work ?
Related
I'm running C# PowerShell code on a remote system and need to get the value of a local variable. PowerShell has a cmdlet named Get-Variable which I'm trying to use. This is my code for trying to fetch the relevant collection of PSVariables (which obviously should contain just one):
psShell.AddScript($"$text = 'someValue'");
psShell.Invoke();
psShell.Commands.Clear();
psShell.AddCommand("Get-Variable")
.AddParameter("Name", "text");
var v = psShell.Invoke<PSVariable>();
Problem is on the last line, I get the following exception:
Cannot convert the "System.Management.Automation.PSVariable" value of type "Deserialized.System.Management.Automation.PSVariable" to type "System.Management.Automation.PSVariable".
Anyone know how to solve this ?
Also, I know of the SessionStateProxy method mentioned on StackOverflow, but as this post of mine shows, it doesn't work for my scenario for some reason.
When PowerShell remoting is involved, only a handful of well-known types deserialize with type fidelity, System.Management.Automation.PSVariable not being among them.
Instances of all other types deserialize as method-less emulations of the original objects, as [psobject] instances with properties containing static copies of the original property values.
In PowerShell, these instances report their type name as the original type name prefixed with Deserialized.
See this answer for background information.
The simplest way to handle such objects is via the DLR:
dynamic v = psShell.Invoke();
Then you can access properties as usual (albeit with runtime binding), e.g., v.Name.
I am currently creating a struct Nullsafe<T> that would wrap a reference type (hence T:class) and behave in a similar way to the Nullable<T> struct. The point is to emulate something close to what the Option<T> in F# does.
I intend to use the type in methods which I need to take special care of nulls. For example, assume I have a reference type class Foo, and the following code:
class Bar
{
public void DoSomethingWithFoo(Nullsafe<Foo> foo);
}
Since I have created an implicit cast operator from T to Nullsafe<T>, then the below code would work fine:
Bar bar = new Bar();
Foo nullFoo = null;
bar.DoSomethingWithFoo(nullFoo);
Foo someFoo = new Foo();
bar.DoSomethingWithFoo(someFoo);
The Nullsafe<T> type is a struct (designed so on purpose, to eliminate passing any null values directly), therefore it is possible for someone to to write the below snippet:
Nullable<Nullsafe<Foo>> nullableNullsafeFoo = null;
// and later
bar.DoSomethingWithFoo(nullableNullsafeFoo);
The snippet, of cource, will not work.
So, I thought it would be a no-brainer to create a cast operator from within my Nullsafe<T> struct, which would handle nullable expressions like the above:
public static implicit operator Nullsafe<T>(Nullable<Nullsafe<T>> nv) => nv.GetValueOrDefault();
Unfortunately, this fails to compile. The compiler seems not to make a difference between the Nullsafe<T> and the Nullable<Nullsafe<T>> types, and throws at me the message:
Is the above a limitation of the compiler, or is it a purposedly intended behaviour? If so, are there any known workarounds?
error CS0555: User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type
I am using:
Visual Studio Community 2017 v15.8.1
.NET Sdk v2.1.400 (as shown by dotnet --version
The project is a library multi-targeting different .NET framework versions - from net20 to netstandard2.0
Update
Is the above a limitation of the compiler, or is it a purposedly intended behaviour?
It seems this is indeed a result of the compiler stripping type information, as described by fellow user Isaac van Bakel.
If so, are there any known workarounds?
Doing as he adviced, I submitted an issue to the roslyn platform.
It's not clear if this is definitely intended, based on the code in Roslyn. The behaviour comes from the compiler stripping the Nullable wrapper from the types involved in the cast in order to correctly catch identity casts from Nullable<Foo> to Nullable<Foo> - but in your case the types are different before the stripping, so it should be allowed.
You could open an issue in the repository - I couldn't find any already open. Someone more familiar with the design of the compiler would be able to weigh in, but it does seem like a bug.
The observed behaviour is in fact intended and confirmed.
A language design discussion thread was created, to address whether this behaviour should be changed in favour of use-cases like the above, or to otherwise provide a better compiler error message to be displayed.
I try to use trial version of third party software written C#.
While I try to use its API, I face up with a strange problem.
I am using visual studio 2015 and I found an interesting extended method signature in their API-SDK
public static class CallExtendedInfoEx
{
public static void AddToSIPMessage(this CallExtendedInfo info, msg);
}
The second parameter type is not exist.Never seen before in C#. I try to give a generic Object parameter as second parameter, and C# Compiler gives a strange error
Severity Code Description Project File Line
Error CS1503 Argument 2: cannot convert from 'object' to '.'
It works with "null"...No compiler error or run time error [ ignored i think ]
How those guys can able to write such a code in C#? Is It Posssible? Any idea?
Note : I suspect from a code obscurification problem...But still i do not understand what is going here
IL_0073: call void [CallExtendedInfoEx::AddToSIPMessage(class [VoIP.CallExtendedInfo,
class [VoIPSDK]''.'')
Well, looking at the ILDASM output, it's rather obvious that the argument has a perfectly valid type. Sure, it's a type that you can't actually name in C#, but it's perfectly valid in CLR at large.
The fact that you can pass null shouldn't be surprising - the argument is a reference type (or convertible from null), so null is a perfectly valid value. On the other hand, expecting passing an object instance is entirely wrong - you can only pass more derived types as argument, not less. It's fine to pass string (more specific) instead of object (less specific), but not the other way around.
Most likely, this is either a method you shouldn't touch (i.e. not part of the public contract of the API/SDK), or you're expected to get instances of the argument from some other method - never using the explicit type anywhere.
This is not valid C# code. Some decompiler probably gave you that code, or the documentation where you copied this out of is faulty.
I've scanned many topics on this site, searched the internet, and experimented with code and nothing has worked. Most people are using separate projects or assemblies which I am not, it's a custom class that exists in the same project and same namespace. If I build the object manually by hard coding it in it works fine but I don't want to do that.
It's a C# ASPX project and I am debugging on IIS from Visual Studio (so maybe that's the issue?).
Type type = Type.GetType("<namespace>."+classname);
Object obj = Activator.CreateInstance(type);
MethodInfo methodInfo = type.GetMethod(function);
response = (<cast object>)(methodInfo.Invoke(obj, null));
I am aiming for variable code where I can write plugins that will be dynamically instantiated. Type.GetType always returns null.
In almost all cases type returns null or when I switch it up with other code I'll get other errors thrown about not finding file or assembly and other errors like this class just doesn't exist...
What do I have to do to be able to build an object dynamically off a string? Let's say I have a class called "Foobar" and I want to do this,
string classname = "Foobar";
Object foobar = new classname(); //easy in PHP, nightmare in C#
Any help would be great, thanks. And before you tell me just to reference another post, I have referenced many and still have no success so if it's not the code than maybe it's how I'm debugging in a browser on IIS?
Type.GetType(String) accepts assembly-qualified type name.
See Type.AssemblyQualifiedName Property
You need to get the type from the assembly is was defined in:
typeof(SomeTypeInAssembly).Assembly.GetType("Namespace.Type")
If it is in the same namespace and assembly as the current object as you say, you should just be able to do the following to get hold of the Type you require:
Type type = Type.GetType(this.GetType().Namespace + "." + classname);
The rest should work as you have it.
Thanks for the suggestions, final code I ended up with below from the suggestions and other post I found on this site.
string fullname = string.Format("{0}.{1}", this.GetType().Namespace, classname);
Type type = Type.GetType(fullname,true);
Baseclass class = (BaseClass)Activator.CreateInstance(type,<parameter1>,...);
MethodInfo methodInfo = type.GetMethod("<method>");
methodInfo.Invoke(class, null);
You can store the return (may need casting) if you want to deal with the return type. Hope this helps someone if they're having issues like me.
Thanks to Rhumborl post, I guess it was an issue in just how I was originally trying to call the Type.GetType function.
String is a native type , witch is automatically inherited from object , since every type (aka class) is an object, so there is no need to do such a thing
In order to allow compatibility with another project that is written in .Net 2.0, we have had to come up with a COM interop (the newer application is in .Net 4.0). This would work because the 2.0 process would be able to use SxS execution with .Net 4.0. In order to have a COM interop from what I understand I have to do something like this:
Type myClass = Type.GetTypeFromProgID("Net4Assembly.Assembly4");
object myInstance = Activator.CreateInstance(myClass);
IAssembly4 assembly4Interface = (IAssembly4)myInstance;
assembly4Interface.CallMethod();
I have already created the COM component and registered it and this works fine. But the problem is that since the project written in 2.0 is outside our department, I want to find a way of doing the casting in line 3 above using reflection. So far I have found a suggestion in Invoke method using Reflection on COM Object
But this doesn't work for me since when I get all the methods of the object in "myInstance" which is of type COMObject, I can only see the methods that are mentioned in that link. I get this error:
Unknown name. (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME))
I think I should somehow cast the COMObject to the interface and then I would have access to the methods? Shouldn't I be able to extract the interface from the COMObject, then call the method using reflection? I tried GetInterfaces() from the COMObject but nothing is returned.
I am not sure if this will work but assuming you have No Misspelled Assembly Name try something like this
Type myClass = Type.GetTypeFromProgID("Net4Assembly.Assembly4");
object myInstance = Activator.CreateInstance(myClass );
//object[] arguments = new object[] //add parameters if youre assembly expects them here
object result = myClass .InvokeMember("SubtractTwoNumbers", BindingFlags.InvokeMethod,
null, myInstance, arguments);