Which features of .NET framework do interop assemblies reference? - c++

We have a Visual Studio solution with about 90 projects. Most of them are built to DLL files, some are written in C++, others in C#. The projects communicate with each other via COM. We use tlbexp to generate TLB files of some C# projects (the ones that are referenced in C++ projects). And we use tlbimp to generate interop DLLs of the C++ projects. I did not completely dig into the topic, but I think, the interop files just define the interfaces of the C++ classes, to make them usable from other projects is that right?
Now, the question is the following: In order to upgrade the entire solution to Visual Studio 2015 and let it compile against .NET 4.6.1, I inspected the resulting assemblies using dotPeek by JetBrains. I can see, that all the C# projects are correctly using .NET 4.6.1, the C++ DLLs themselves are native and do not reference any .NET. Now, what surprised me was the fact, that dotPeek told me, the interop DLLs (which resulted from the C++ projects), were referencing .NET 4.0.
After a "wonderful" day of trying to make them reference .NET 4.6.1 and lots of research, I finally did not find any way to make the interops reference .NET 4.6.1. Is that even possible? My current guess is, that all interop DLLs generated like this reference just the basic .NET 4.0, just because it uses the same CLR as .NET 4.6.1.
Is that right? It should be possible to execute the assemblies on any system that has .NET Framework 4.6.1 installed, shouldn't it?

You are getting bad info from dotPeek. It doesn't tell you how it figured out what .NET version is targeted. It can be specific on a .NET assembly that's generated by a compiler. Because it automatically inserts a [TargetFramework] attribute into the assembly, it states what version of .NET you selected when you built the project.
But an interop assembly does not specify a .NET version, primarily because it isn't generated by a compiler. Note how you never specified a version when you ran Tlbimp.exe. And can't. All that dotPeek can figure out is that it targets .NET 4, cued by the metadata format. No way it can be more specific.
And it does not matter, since the interop library does not use .NET Framework features. The only point of the library is that your program can use the COM component features. So the version number that dotPeek reports just doesn't matter; any .NET 4.x framework can use the library.
You don't have a real problem.

Related

Why Visual C++ Redistributables needed?

I'm installing GTA 5 and it's also installed Visual C++ Redistributables. This got me curious about something, because this happens a lot.
As far as I know, these are needed for linking to VC++ libraries, but I already have .NET 4.8 installed on my system.
I thought when C++ (managed) gets compiled to MSIL, it would then just use the standard .NET Framework libraries.
So essentially the question is, since the .NET Framework libraries are present, why do additional VC++ specific libraries also need to be installed?
Thanks!
Simple answer:
".NET runtime" is to C# as "Visual C++ runtime" is to C++
Explanation:
Applications written in C# or "managed code" require a specific version of the .NET runtime installed. The .NET runtime not only includes the interpreter for the virtual machine code, but also provides all the standard class libraries an application developer might reference in his code. Applications written in C# will need the .NET runtime installed on the target computer.
Applications written in C/C++ or a "native code" typically link with a set of libraries to provide the common set of functions and classes provided by the language standard (e.g. printf and std::string). The application developer can choose to statically link these functions directly into his EXE. But it's often advantageous to link dynamically with a DLL version of these libraries so they can be shared across the system or with binaries within the application. Hence, the redistributable package.
C++ compiles to native code and does not use the .NET runtimes. It uses the VC++ runtime (*), which can be either statically or dynamically linked. In the latter cases, this requires the VC++ redistributables.
(*) It is technically possible to build an application with VC++ that does not use the VC++ runtime at all, but that sacrifices language features and is not common.
Managed flavors such as C++/CLI compile to mixed mode assemblies, which still have an unmanaged part with the same requirements.

Is it possible to create a C# DLL of C++/CLI code using .Net Core 3.1 on Linux

This might be a very specific question. But it might be interesting for some other people, too.
The setting might be quite common: we develop an embedded device using C++ and Linux and have a build system for this. With our device we ship a C# desktop app using a DLL based plugin mechanism. The plugin contains the shared logic used both on the embedded device and the app. To keep processes easy it would be best to create the DLL on our Linux build system (hence I would like to use .Net Core and not "normal" .Net).
As far as my trial and error showed it's not possible - even with .Net Core 3.1. Can you confirm this? The software is for windows only (although it's compiled on Linux) - so theoretically it could possible since .Net Core supports CLI/C++ in Version 3.1 (https://devblogs.microsoft.com/dotnet/announcing-net-core-3-1/).
What I tried:
I compiled pure C# code on Linux to an exe running successfully on windows using the console app dotnet
I successfully created a simple C++/CLI test app on Windows using sample code following this guide: https://devblogs.microsoft.com/cppblog/an-update-on-cpp-cli-and-dotnet-core/
Finally I took the (probably for too naive) approach to replace the test app's .vcxproj with the .csproj of step 1 (.csproj seems to detect files automatically). I got the following error message:
quote CSC : error CS5001: Program does not contain a static 'Main' method suitable for an entry point [/home/vagrant/Projects/cpp_dotnet_on_linux/cs_on_linux.csproj]
Is there something I can improve or is the task just impossible (adding the cpp-files manually to .csproj, ...)? I'm afraid it's just technically impossible because I guess .Net Core is missing a C++ compiler on Linux but I'm not sure.
C++/CLI is not support on Linux.
Some sources:
https://devblogs.microsoft.com/cppblog/the-future-of-cpp-cli-and-dotnet-core-3/ :
We don’t currently have plans for C++/CLI for targeting macOS or Linux. Additionally, compiling with “/clr:pure” and “/clr:safe” won’t be supported for .NET Core.
https://github.com/dotnet/coreclr/issues/659#issuecomment-539742740
C++/CLI on Linux will not be supported and would be very challenging. It would require Microsoft VC++ to support Linux or require Clang or GCC to support C++/CLI. Those are both huge projects with uncertain payoff. It is also unclear if Clang or GCC would ever allow us to upstream our changes. Maintaining an up-to-date fork of a fast moving compiler project forever is very expensive. We have no plans to take on either of those projects.

How to run C++ executable in Windows PE?

I have an executable I made using a CLI console application with Visual Basic 2010. I can run the program completely fine from my developer machine.
However, when I copy the executable over to another machine, re-boot to a pre-installation environment and run the executable again, nothing happens at all. There are no errors shown or anything.
My guess is the executable can't run without certain dependencies that aren't loaded at this environment, but I need it to work in a PE.
Any ideas on whats going on?
First of all, since the question is tagged "c++" and you mention C++/CLI several times, I assume that "Visual Basic 2010" is a typo for "Visual Studio 2010". But either way, whether you've written the application in Visual Basic (VB.NET) or C++/CLI, the problem is exactly the same.
My guess is the executable can't run without certain dependencies that aren't loaded at this environment, but I need it to work in a PE.
That's exactly correct. You've written an application that targets the .NET Framework. Somewhat like Java applications requiring a JVM, .NET applications require that the .NET Framework be installed in order to run (or a compatible alternative implementation, like Mono). Unfortunately, Windows PE does not support the .NET Framework.
Note that it is irrelevant whether you've written a WinForms, WPF, or Console application. Although they present their UI in very different ways, they all depend on the .NET Framework being installed.
You will need to (re-)write the application in a different programming language, one that generates native code without any dependencies on the .NET Framework. C and C++ are popular choices. If you choose to use C++, make sure that you create what Visual Studio calls a "Win32" project. This is one that targets the underlying operating system APIs directly (i.e. a native application) and does not have a dependency on the .NET Framework. Stay away from anything that has ".NET" or "CLR" in its description.
I don't really have a full comprehension of when an application is using .NET or not... I am just used to Linux C/C++ development. I hate Microsoft shit
It uses .NET whenever you use the .NET Framework libraries/classes in your code. I'm not really sure why this is so difficult to understand. The same problem could easily exist on Linux if you were using a third-party library that was not available in certain environments for whatever reason. This is not Microsoft's problem, it's an issue of using the wrong tools for the job. The .NET Framework is an object-oriented wrapper around the native APIs that makes it much easier for people to get up and running writing programs for Windows. But if you're "used to Linux C/C++ development", you should have little trouble writing a simple console application that targets the native APIs directly without using .NET.
If your hatred for "Microsoft shit" has turned into an allergy, you can avoid Visual Studio entirely and download MinGW, which is a Windows port of the GCC compiler you're probably used to. Combined with your favorite Windows port of Vi, you're working in an environment very similar to the one you're used to. And since GCC doesn't support C++/CLI or the .NET Framework, you won't have to worry about getting stuck picking the wrong option.
The .Net framework has been supported as an optional package install during your PE build process for the past couple versions of WinPE. I write code in C# that I run in WinPE everyday. I have yet to find a good way to debug in a manner where I can walk through break points, etc... though. My best option has just been a lot of logging and a global Exception catch around my main entry point that will write out a full stack dump. You can attach to your app as a remote process in a VM running WinPE, but if you need to catch something early in the execution you'll have a difficult time.

Visual C++ 2010 and Native executable file

Native exe!
that means my program can run easily without any requirement?
even if I use .net classes?
You know I want to write a program that is so light and I don't like to use C# or any other .net programing language because all of them need .net-framework 4.5.
Just think a 2.5 MB programm needs a +250 MB .netframework.
New Update - 12/01/2016:
It's almost 4 years ago when I asked this question. As you know Dotnet Native is announced. It's an interesting feature which compile IL into native code.
Compiling Apps with .NET Native
.NET Native is a precompilation technology for building and deploying
Windows apps that is included with Visual Studio 2015. It
automatically compiles the release version of apps that are written in
managed code (C# or Visual Basic) and that target the .NET Framework
and Windows 10 to native code. Typically, apps that target the .NET
Framework are compiled to intermediate language (IL). At run time, the
just-in-time (JIT) compiler translates the IL to native code. In
contrast, .NET Native compiles Windows apps directly to native code.
For developers, this means:
Your apps will provide the superior performance of native code.
You can continue to program in C# or Visual Basic.
You can continue to take advantage of the resources provided by the .NET Framework, including its class library, automatic memory
management and garbage collection, and exception handling.
Last I checked none of the .NET frameworks were 250+ MB! Yes, the offline installer for .NET Framework 3.5 SP1 is 231MB but it contains x86 and x64 versions of .NET 2, 3 and 3.5 sp1.
You should read this http://www.smallestdotnet.com for details on sizes of various versions of the installers.
Now on to your question:
Yes, It is a little annoying to have your clients install a big framework, even 20-40MB does get annoying. With .NET, the advantage is the ease of programming (In my opionion) compared to other Native options.
Your native options are:
MFC - You need only the VS runtimes installed, which is 1-2MB and is usually installed on newer pcs. Also, you can ship your application with the MFC libraries packaged into a dll which is again <2MB
The trade of here is you need to program in C++, the libraries overall are a very thin layer over the native libraries. and people have had harsh opinions about MFC. I've barely just tried it.
Win32 API - This is going all bare bones, and quite difficult, you could use C or C++ but you'd really have to know a lot about the Win32 API and how windows itself works (Stuff like windows messages, hwnds etc) Its not fun, believe me. But during deployment you would not need any external libraries.
There are tons more options, see here:
Native Windows Application Development Options
https://stackoverflow.com/questions/2711599/what-programming-language-should-i-use-to-create-small-native-windows-applicatio
Here are some links on MFC that might help:
Want to learn Windows Programming,some suggestions?
How do I decide whether to use ATL, MFC, Win32 or CLR for a new C++ project?
C++ MFC vs .NET?
https://stackoverflow.com/questions/557114/stick-with-mfc-or-go-to-net
you are able to create native exe by using c++ Win 32 projects.
Alas, nearly everything requires a download runtime library and even if you have one installed, you'll need to download updates for them almost continually. Even Microsoft C++ apps nowadays come with security updates that have to be installed if you've compiled your app with them.
But.. there is a solution of sorts. If you use C++, it has a feature where only the things you use are compiled into the final app. Normally, this would require linking with all the library dlls, but if you statically link with the library, you will end up with a single .exe that is as small as can be, and you will not need any dlls (as all the code contained in the library will be compiled into the .exe).
The benefits are debatable compared to dlls, but as MS has pretty much broken the idea of shared dlls in .NET (ie, you practically have to put all the shared dlls in the same directory as your running app, giving you a nightmare in maintenance if you have these shared dlls spread around all your apps) then there's not much of a difference anymore. Static linking is getting a little bit of a comeback and sounds like its what you want.
For modern C++ development, you'll probably want to take a look at Qt instead of MFC. Its a lot nicer to use and is cross-platform so you can run Qt apps on your Android or Linux platforms as well as Windows.

Problems upgrading VS2008 to VS2010 with Managed and Unmanaged C++

I have a VS2008 Professional solution that I tried to convert to VS2010 Professional (RTM from MSDN download) today and I am experiencing some problems with some unmanaged and managed C++ DLLs that are referenced by a C# application.
The C# application is set to target .NET 3.5 (as it was in the VS2008 version) but when I try and compile it I get a lot of warnings like:
The primary reference "xxxx.dll" could
not be resolved because it had an
indirect dependency on the .NET
Framework assembly "(various assembly
names)", Version 4.0.0.0 ... which has
a higher version "4.0.0.0" than the
version "3.5.0.0" in the current
target framework
and ultimately I get a failure to build.
From this I understand that it is a mismatch in .Net framework version. So I look at the properties of the unmanaged C++ DLL project and under "Common Properties->Framework and References" I can see "Targeted framework: .NetFramework, Version=v4.0"
So I go WTF!?!?!?, why does a pure C++ DLL now target a .Net framework when it sure as hell didn't in the VS2008 version. I then added on to that exclamation as there appears to be no way to change this. I also look at the managed C++ and see the same thing: targeting .Net version=v4.0 and again no way to change this at all.
In the C++ General properties there is an entry for "Common language runtime support" and I have set this to "No common language run time support" but that hasn't seem to have done anything.
So I have two questions:
Why has my pure C++ DLL now been tagged as targeting a .Net framework?
How can I change/remove this targeting?
Solution
As per Hans' reply and the link he supplied I now see that I have 3 choices:
Stay at VS2008 and everything works
Keep both VS2008 SP1 and VS2010
installed so that I can have .Net
3.5 c# applications and c++ managed code as per the link supplied by Hans.
Move everything to VS2010 and move
to a minimum of .Net 4.0 for all my
c# apps
I am really annoyed to have to make that choice as MS has deliberately chosen to break functionality when moving from VS2008 to VS2010. This is not the sort of behavior I expected. I was expecting to convert the project and have it compile with no issues in the same manner that moving from VS2005 to VS2008 worked.
Fortunately I do have a need to go to .Net 4.0, but I just wasn't expecting to have to do it so soon.
Update
I decided to move to .Net 4 framework and encountered problems with referencing managed c++ projects from c# projects. I was getting errors like the following when trying to add the reference to the c++ managed code project
A reference to 'myproj' could not be
added. An Assembly must have a 'dll'
or 'exe' extension in order to be
referenced.
Google lead me down the path to "cli c project cannot be referenced from c project allowing only assembly dll" which turned up that there was an extraneous "\" in the output path of the managed c++ project. The original VS2008 output path was specified as
$(SolutionDir)\$(ProjectName)\$(Configuration)\
But in the VS2010 project the SolutionDir macro has a trailing "\" (or the VS2008 version didn't care about it) giving a path like
c:\projects\thisproject\solution\\projectname\configuration\
And VS2010 barfed over that path when trying to add a reference to the managed c++ code. My solution was to change the output path to be
$(SolutionDir)$(ProjectName)\$(Configuration)\
And now I am (sort of) happy
Keep your eyes on the ball, the warning you get is for a managed C++ assembly. And the platform target setting for an unmanaged DLL is of no consequence, it won't use any .NET references while being built.
Yes, they could not make the platform target setting editable in the C++ IDE, the VS2008 tool chain is required to build C++/CLI assemblies for 3.5. This blog post explains the workaround. You can upvote this feedback article if you're unhappy with that.