Why can't enumerations from different DLLs be accessed through late binding? - c#

I was trying to find out how I can access Excel's enumerations through COM interoperability using C#.
Its simple to do it using early binding but with late binding I only found out that I can access enums in the same file.
If the enumerations are in a different DLL they can't be accessed. So either I use the integer values or create my own enums.
Is it really not possible to access them through late binding? If so, why? I would expect that early binding is late binding code made easy by the IDE or so.

If the enumerations are in a different DLL they can't be accessed. So either I use the integer values or create my own enums.
It is by definition, not possible to access pre-defined enums via late-binding. Obviously they will appear as "integers" to .NET. Sure you could cast some int to an enum that you have defined or perhaps a constant but such code is only for your benefit and does not represent the strong contract the COM library usually publishes.
Is it really not possible to access them through late binding? If so, why? I would expect that early binding is late binding code made easy by the IDE or so.
Early-binding makes use of either COM Type Libraries or COM Interop libraries. These are essentially .NET wrappers around COM types by providing C# or VB.NET-familiar types. With it you get intellisense in the form of statement completion; parameter help; and method help. The compiler will help you in any mistakes you might make at compile-time. Early-binding only works if the type library or COM interop library is present.
Late-binding gives you nothing in the form of intellisense. There is no indication of what objects are available; what methods are present; nor what parameters to pass. Your code may compile but you could still get runtime errors. Late binding does not use nor require type libraries nor COM interop libraries.
In addition, the term late binding means something quite specific to COM. It generally involves the invoking of IDispatch to get a list of method names. I'm not sure that .NET's enumType.GetField("Bar").GetValue() qualifies.
Late Binding Example
Late binding C# code:
// You will get no intellisense help here
var progId = "Excel.Application";
dynamic excelApp = Activator.CreateInstance(Type.GetTypeFromProgID(progId));
excelApp.Workbooks.Add = true; // VS happily lets me type all this
dynamic workSheet = excelApp.ActiveSheet; // hope this all works at runtime
Late binding or not
Isn't this example accessing an enum via late-binding with reflection? The difference is that it only works for the same file
Perhaps, it's a form of late binding. I would probably use the term decoupled.
Late-binding in the COM world is generally used in one or more of the following scenarios:
a) don't know what you will be interfacing with ahead of time
b) you do know, but you don't have access to any type library either because its not installed or the developer never created it
c) want to decouple your app from any specific version of the COM library
The example you supplied which uses enumType.GetField("Bar").GetValue(null); tells me a few things:
you know you are dealing with Excel
you have access to a form of "type library" - one that contains definitions. In this case enum constants
You are somewhat coupled to Excel
With this in mind, I'm not sure why you want to follow a late-bound route. You seem to be taking the harder approach.
Tell me more
C# create excel sheet late bound

Related

C# create excel sheet late bound

Using winforms, C# FW4.5 to open an excel sheet with late bound, like this:
objExcel = CreateObject("Excel.Application")
Now I want to use the InvokeMember method, but I don't know all the members of excel I can invoke.
For example, I know I can call it like this: InvokeMember("Close",... in order to close excel, but where can I find list of all the members I can invoke and what each one of them does?
Late-bound
Using winforms, C# FW4.5 to open an excel sheet with late bound, like this:
If you must use late-binding, using c# 4.0's dynamic keyword is a whole lot easier than InvokeMember, though it won't show you what methods you can invoke ahead of time.
Check out the following code that uses late-binding via the dynamic keyword. Notice how Visual Studio allows me to type in any old thing. Though auto-complete for the final members aren't available, it does show members for items I've used already. I won't know until runtime whether I got it right (such is the limitation of late-binding this way).
C# now supports dynamic late-binding. The language has always been strongly typed, and it continues to be so in version 4.0. Microsoft believes this makes C# easy to use, fast and suitable for all the work .NET programmers are putting it to. But there are times when you need to communicate with systems not based on .NET....The dynamic keyword in C# is a response to dealing with the hassles of these other approaches Tell me more
...and more specifically:
The COM interop scenario that the C# team specifically targeted in the C# 4 release was programming against Microsoft Office applications, such as Word and Excel. The intent was to make this task as easy and natural in C# as it always was in Visual Basic. Tell me more...
Early-bound
OP:
Now I want to use the InvokeMember method, but I don't know all the members of excel I can invoke
Though late binding is fine, even with dynamic, I like early binding. To get a list of methods, it's much easier and type-safe to use early binding via adding Microsoft.Office.Interop.Excel to your project.
Early binding:
var application = new Microsoft.Office.Interop.Excel.Application();
application.Visible = true;
application.ShowWindowsInTaskbar = true;
Here it is in VS:
C# 4 Goodness
c# 4 brings with it some stuff you'll only see when dealing with COM, like indexed properties - something not possible in c# types.
You can’t define types in C# that have indexed properties, but you can use them provided you’re doing so on a COM type more
Some smaller language features in C# 4.0 are supported only when writing code against a COM interop API
e.g.
ws.Range["A1", "B3"].Value = 123;
...is a whole lot easier than pre-c# 4:
ws.get_Range("A1", "B3").Value2 = 123;
C# 4.0 supports indexed properties on COM interop types. You can’t define types in C# that have indexed properties, but you can use them provided you’re doing so on a COM type more...
Tell me more
C# 4.0 - New C# Features in the .NET Framework 4, MSDN Mag July 2010
Dynamic .NET - Understanding the Dynamic Keyword in C# 4, MSDN Mag Feb 2011

COM Object Registration--Multiple allowed?

I have two COM objects with different GUID values, but the same name. One is a newer version of the other. What happens when I register both using Name.exe /regserver? I've looked in the registry, and they both show up with the same ProgID, but their respective GUID values are different. They point to their separate locations on the hard drive. Is this a problem?
I'm trying to get the old version of a project to work alongside the new version of a project (but not running at the same time), and I think these two things are fighting.
The COM objects were created in VB6. The code that uses them is C#. They are added to their individual C# projects as references. When one is registered, I can't compile the other (nor run successfully).
What other information would be helpful while investigating this issue?
Converting my comment into an answer:
You have created a new version of a component which is not backward compatible with the old version.
You really should change the ProgID to indicate that this is effectively a new component. Client apps will have to explicitly target either the new component or the old one. People often just append a version number (e.g. 2) to the ProgId.
You are violating hard COM rules. Either your replacement must be an exact match with the component you replace. Or you must generate a new version that:
Uses a different [Guid] for the coclass, you did that correctly.
Uses a different ProgId, you didn't do that. Boilerplate is to include a version number in the ProgId itself. So a Foo.Bar becomes Foo.Bar.2
Uses different [Guids] for the interfaces implemented by the class. This is easy to overlook since they are hidden so well in a VB6 component. Crucial however whenever the class is used from another apartment. COM needs to find the type library for the component so it knows how to marshal the interface method call. Be sure to declare your interfaces explicitly in your C# code.
The best way to double-check all this is by running OleView.exe, File + View Typelib command. That decompiles the type library content back to IDL, you will see the guids and interfaces. If you want to create an exact substitute for the old component then everything must match exactly. Exact same guids, exact same interfaces with the exact same order of methods and exact same arguments.
I haven't ever accessed VB6 ActiveX exes from .NET (just dlls), so this is a shot in the dark (and is weak enough to be just a comment except it is too long).
Perhaps you can create / export a .tlb each for the two VB6 components to compile your C# against. You shouldn't need the exes to compile.
Next manually add the registry entries as if they had separate Programmatic IDs (say MyComponent.ServerClass.1 and MyComponent.ServerClass.2) and then load them by name in your C#.

How does .NET's Primary Interop Assembly Embedding work?

I am researching the .NET Common Language Infrastructure, and before I get into the nitty-gritty of the compiler I'm going to write, I want to be sure that certain features are available. In order to do that, I must understand how they work.
One feature I'm unsure of is the .NET Primary Interop Assembly embedding. I'm not quite sure how .NET goes about embedding only the types you use versus the types that are exposed by the types you use. From the bit of research I've done into this, I've noticed that it emits a bare-bones interface that utilizes vtable gap methods, where the method name format is VtblGap{0}_{1} where {0} is the index of the gap and {1} is the member size of the gap. These methods are marked rtspecialname and specialname. Whether this is accurate or not, is the question.
Assuming the above is true, how would I go about obtaining the necessary information to embed similar metadata into the resulted application?
From what I can tell, you can order the MemberInfo objects obtained via their metadata tokens for the order, and the dispid information is obtained via the attributes from the interop assembly. The area I'm most confused on are the interfaces that are imported that seem to have no direct correlation with the other embedded types, sequentially indexed interfaces that seem to be there for versioning reasons. Is their inclusion based off of their indexing or is there some other logic used? An example is Microsoft.Office.Interop.Word, when you add a document to an Application and, in doing something with it, it imports the document, its events, and so on.
Here's hoping someone in-the-know can clue me in on what else might be involved in embedding these types.

How does COM support optional parameters?

But, how does COM support them? Does C++ support them? Is is ignorant of me to assume that all COM code is written in C++? Or is COM just a methodology, a way to architect your app?
I'm curious. I've been writing lots of COM automation from C# lately and this question just occurred to me.
this link might help answer your question about optional parameters (the answer is "yes" you can do them):
http://msdn.microsoft.com/en-us/library/f25e2b6b%28VS.80%29.aspx
com is a binary specification. you can technically create a com object (server) in any language. the microsoft languages obviously (sinisterly?) make it easier than others because they wrote the spec. create a com server in straight C is possible ... technically. in reality it is a massive undertaking.
best regards,
don
If you're working with COM and Automation in C/C++ (or old versions of Delphi), you should use VARIANTs for the parameters that you want to make optional. Also, optional arguments as defined in C++ style are not supported for COM.
That said, for those VARIANTs that you are to provide when you are calling another object and you want to specify optional parameters (say, when talking to MS Word or Excel via Automation), you will need to initialize those VARIANTS with type VT_ERROR and the scode field set to DISP_E_PARAMNOTFOUND.
When receiving calls from other objects that are capable of omitting parameters (VBScript, JScript), you need to check all your VARIANTs for cases where the type has been set to VT_ERROR and the scode field is DISP_E_PARAMNOTFOUND.
The .NET equivalent is to use an object set to Type.Missing for those parameters mapped to COM optional parameters. The following link may be useful in seeing both sides of the story.
.NET4Office : Type.Missing, C#, and Word (MSDN Blog)
All of this is rooted in how older versions of VB (6 and previous) handled optional arguments. Here is a MS Support KB link that is pretty succinct.
How to pass optional parameters when you call a function from C++ (kb238981)
To address your other questions, it is incorrect to assume that a majority of COM objects are written in C++, as COM is strictly about declaring interfaces and layouts of interfaces in a well known manner. It doesn't matter what language or tools are used to make COM objects so long as they observe and obey the layouts for the interfaces that are supported.
Finally, you're correct about COM being a methodology- not quite in the sense of setting architecture for any specific app, but in making it possible to strongly define interconnected components that may make up an application or may be made available to other applications.

What is a dynamic language, and why doesn't C# qualify?

Listening to a podcast, I heard that C# is not dynamic language while Ruby is.
What is a "dynamic language"? Does the existence of dynamic languages imply that there are static languages?
Why is C# a dynamic language and what other languages are dynamic? If C# is not dynamic, why is Microsoft pushing it strongly to the market?
As well why most of .NET programmers are going crazy over it and leaving other languages and moving to C#?
Why is Ruby "the language of the future"?
What is a dynamic language?
Whether or not a language is dynamic typically refers to the type of binding the compiler does: static or late binding.
Static binding simply means that the method (or method hierarchy for virtual methods) is bound at compile time. There may be a virtual dispatch involved at runtime but the method token is bound at compile time. If a suitable method does not exist at compile time you will receive an error.
Dynamic languages are the opposite. They do their work at runtime. They do little or no checking for the existence of methods at compile time but instead do it all at runtime.
Why is C# not a dynamic language?
C#, prior to 4.0, is a statically bound language and hence is not a dynamic language.
Why is Ruby the language of the future?
This question is based on a false premise, namely that there does exist one language that is the future of programming. There isn't such a language today because no single language is the best at doing all the different types of programming that need to be done.
For instance Ruby is a great language for a lot of different applications: web development is a popular one. I would not however write an operating system in it.
In a dynamic language, you can do this:
var something = 1;
something = "Foo";
something = {"Something", 5.5};
In other words, the type is not static. In a statically typed language, this would result in a compiler error.
Languages such as C, C++, C#, and Java are statically typed.
Languages such as Ruby, Python, and Javascript are dynamically typed.
Also, this is not the same as "strongly or weakly" typed. That is something different all together.
I'm stunning at the way c# it's embracing a fundamental set
of programming paradigms.
We can say that c# alows a rich object oriented programming,
a rich component oriented programming,
a well integrated functional programing,
a complet set of query operations over differents types of data sources (linq),
a elegant aproach of cocurrent programming through pLinq and parallel extensions,
in the next release (c# 4.0) will have powerfull dynamic capabilities,
and it's almost sure that in c# 5.0 will have a solid set of meta-programming
features.
With just can say that c# it's doing a great job of integrating all this powerfull
stuff in just one tool box. That's in my opinion it's the way it must be,
because skipping from one programming language to another it's almost always very painfull.
C# is a statically typed language, because the type of every object you're working with needs to be known at compile time. In a dynamic language you don't need to know what type an object is at compile time. Maybe you import some classes that you don't know before hand, like you import all classes in a folder, like plugins or something. Or maybe even the type of an object depends on user-interaction.
You can achieve a similar effect by using interfaces or base classes, but it's not completely the same because you are limited to using classes that explicitly inherit from or implement that interface.
In dynamically typed languages it doesn't care what the type is when you compile it, it'll try to call the method you specified by name, if that method doesn't exist on the object it'll throw a run-time exception, so it's up to the programmer to ensure that that doesn't happen or handle it appropriately. You gain flexibility, but lose out a little on compile-time error checking.
Looking at the Wikipedia entry, we see that a dynamic language is one that does things are runtime that most do at compile time. Typically, in a dynamic language, a variable could change types quickly and easily, and there typically is no separate compile step (but rather either interpreted execution or really fast compiling). C# is a more conventional language, using variable declarations and being compiled.
The Wikipedia entry lists numerous dynamic languages.
"X is the Y of the future", on the other hand, means that somebody's trying to sell you something. (Not necessarily literally, but trying to influence your beliefs in a way convenient to the speaker.)
Did you know that VB6 is both static and dynamic?
If you declare variables with a given type, then you get static behaviour:
Dim name as Label
You can now only access members of name that are Labels and intellisense knows that.
If you have a class and add the implements keyword, then your class can implement methods of another class. This is inheritance of interface that VB6 allows. You can get some runtime polymorphism.
You can also declare variables like this:
Dim proxy As Object
Now intellisense doesn't give you any help and VB6 will allow you to do anything you like with proxy:
proxy.foo()
This line can sit inside a compiled and running program and cause no offence, especially if its not run itself. Its only when the line is run does the lookup take place.
You can also perform:
set proxy = <any instance>
and this will run. It doesn't matter whether <any instance> has a foo method or not.
And then any instance of any class that does implement foo can be assigned and the method called and VB6 will be happy.
Note that there are run-time performance penalties as you become increasingly dynamic.
In C# 3.0, the types of everything needs to be known at compile-time. It's a static language. A dynamic language uses dynamic dispatch at runtime to decide the type of things and what methods to call on those things. Both types of languages have their advantages and disadvantages. C# 4.0 will add dynamic capability. Anders Hejlsberg gave a great talk on static v.s. dynamic languages and C# 4.0 at PDC.
A dynamic language is generally considered to be one that can dynamically interpret & generate code at runtime. C# can't do that.
There are also dynamically typed & statically typed languages. Dynamically typed means that the type of a variable is not set and can change throughout the program execution.
The words static and dynamic are not cleary defined.
However, what is most often meant is two issues:
1) In static languages, the type of a variable (that is, the type of value the variable can contain or point to) cannot change during the course of a program. For example in C#, you declare the type of a variable when you define it, like:
int a;
Now a can only ever hold an int value - if you try to assign a string to it, or call a method on it, you will get a compile type error.
2) In static language the type of an object cannot change. In dynamic languages, an object can change in that you can attach or remove methods and properties, thereby basically turning it into a completely different object.
c# is statically typed, ie int i =0; try setting i to be a string. the compiler will complain,
where as python a variable that used to hold an integer can then be set to hold a string,
Static: Types are final,
Dynamic: Types can be changed,
c# is trying to add more dynamic like features, var for instance
There is no true "language of the future".
Different languages have different purposes.
At most, you could say Ruby is a language of the future.
According to Wikipedia:
Dynamic programming language is a term
used broadly in computer science to
describe a class of high-level
programming languages that execute at
runtime many common behaviors that
other languages might perform during
compilation, if at all. These
behaviors could include extension of
the program, by adding new code, by
extending objects and definitions, or
by modifying the type system, all
during program execution. These
behaviors can be emulated in nearly
any language of sufficient complexity,
but dynamic languages provide direct
tools to make use of them.
Most dynamic languages are dynamically typed, but not all.
Ruby is a dynamic language and C# is not, since Ruby is interpreted and C# is compiled. However, C# does include some features that make it appear dynamic.
A language is dynamically typed, that means a variable in that can be used for anything.
Variables are not typed, values are. A variable can have the value of any primitive type, or it can reference to any object.

Categories