Is Platform Toolset v110 incompatible with .NET 3.5? - c#

This is with Visual Studio 2012 Ultimate Update 3.
I have a C# project that targets .NET 3.5. This project uses a C++/CLI dll which is also compiled for .NET 3.5.
I have noticed that if the C++ dll is compiled with Platform Toolset v110, then although I can add it to the C# project, and see the types in Intellisense, the compiler itself doesn't see any of the types. It complains that they do not exist and that I am missing an assembly reference. This does not happen if it is compiled with Platform Toolset v90.
If I then re-target the C# project to .NET 4 or 4.5, then it sees the types alright. The types do exist in the assembly and can be seen in the object explorer or Ildasm.
It therefore seems that the use of Platform Toolset v110 makes it impossible to use the dll from a .NET 3.5 project, even though the dll is compiled for .NET 3.5.
Is this normal and/or documented behavior? Is there any way around this other than either downgrading the C++/CLI project to Platform Toolset v90 or upgrading the C# project to .NET 4?

As always Toolset v110 does not support any .Net version other than 4.5. Officially, to change the target framework you must change the platform toolset to a version that supports the target .Net version (e.g. Windows 7 SDK for .net 2.0-3.5 SP1). This involves changing TargetFrameworkVersion in the project file as well as switching to another platform toolset.
That said, the toolset is just a bunch of msbuild rules so you may get the the compiler to retarget the .Net version by changing the vcxproj and global msbuild rules
in project file. Olga Arkhipova from the VC++ team comes up with this:
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<RealTargetFrameworkVersion>$(TargetFrameworkVersion)
</RealTargetFrameworkVersion>
Add a file to 'C:\Program Files (x86)\MSBuild\4.0\Microsoft.Common.Targets\ImportBefore
<Project ToolsVersion="4.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TargetFrameworkVersion
Condition="'$(RealTargetFrameworkVersion)' != ''">
$(RealTargetFrameworkVersion)
</TargetFrameworkVersion>
</PropertyGroup>
</Project>

Related

Update C# Windows Forms Project to Latest C# Version

I have a C# Windows Forms project but I need to update it to the latest version of the C# language but I don't understand the documentation for updating, does anyone have an example of how to do this?
I'm using version 4.6 of Net Framework, I've tried it with 4.8 too
You can set the LangVersion property in the .csproj file to specify the C# version you'd like to use. You can set it to a specific version, or use "latest" to set it to the latest version compatible with the compiler:
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
</PropertyGroup>
</Project>
Be aware that only certain versions of the C# language are compatible with specific .NET versions and MSBuild Versions. The highest version of C# compatible with .NET Framework is 7.3.
You can find more information, including C# / .NET version compatibility, here:
C# language versioning

Relationship between PlatformTarget and RuntimeIdentifier in .NET 5

I'm confused about the relationship between RuntimeIdentifier and PlatformTarget in .NET 5.
My .NET 5 C# project runs and publishes fine, but PlatformTarget is 'AnyCPU' and RuntimeIdentifier is 'win-x64'.
From Microsoft's documentation, RuntimeIdentifier is "used to identify target platforms where the application runs".
https://learn.microsoft.com/en-us/dotnet/core/rid-catalog
Isn't this what 'PlatformTarget' is supposed to do?
I tried using RuntimeIdentifers (plural) which I've seen before (perhaps .NET Core 3?), but the project doesn't compile with this:
<RuntimeIdentifiers>win-x64;win-x86</RuntimeIdentifiers>
From my current project file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> -> RuntimeIdentifier is required since SelfContained is 'true'
...
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
...
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
...
</Project>
The term of "AnyCPU" means that it will have binaries that is compatible for both 32bit and 64bit. This means it is not meant to be specific for either 32bit and 64bit, and this "AnyCPU" is mostly used in older .NET Framework project, not commonly used in SDK project style that is mainly used in .NET Core projects.
These .NET Core projects include single targeted .NET Core project or multi targeted .NET Core projects, such as those that has with multiple target (usually known as TFM).
Since .NET 5.0, the TFM can be cross platform TFM such as net5.0 or .NET 5.0 target with specific OS, such as net5.0-windows or net5.0-ios. IF you want to specify .NET 5.0 class libraries that runs on Windows for 64bit, you have to specify both TFM and RuntimeIdentifier (usually called RID).
Therefore we should not use the older "AnyCPU" with combined Conditional "Release|AnyCPU". By default, any TFM without RID is always the same as having AnyCPU in these SDK project model.
For example, for targeting .NET 5.0 on Windows on both 64bit and 32bit:
<PropertyGroup>
<TargetFramework>net5.0-windows;</TargetFramework>
<RuntimeIdentifier>win-x64;win-x86</RuntimeIdentifier>
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
</PropertyGroup>
The SDK projects has attribute Sdk="..." in the header, and this SDK will drive the reference resolutions for your project.
I recommend you to remove those PropertyGroup that has older "Release|AnyCPU" or "Debug|AnyCPU" combinations, because these combined MSBuild project syntax is not relevant for any .NET Core SDK project model.
One thing to be noted is when you have more than one RID like those in the sample above, you have to run publish for each RID you support.
Therefore, in order to have both 64bit and 32bit, you have to publish separately for each RID.
SO you have to run these:
dotnet publish yourproject.csproj -r win-x64
dotnet publish yourproject.csproj -r win-x86
See also the official doc on publishing single file executable:
https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file
It's true that the pile of properties is difficult to understand (Platform, Platforms, PlatformTarget, TargetFramework (Moniker), and RuntimeIdentifier). Here is my current take on the properties - keep in mind that I have still have questions because of the results of my experiments).
Platform, Platforms, and PlatformTarget: These properties are kind of synonyms (Platforms plural is required to hold multiple platform specifiers) and refer to the bitness/CPU architectures such as AnyCPU, x86, x64, and Arm. I always think "hardware" for this property.
TargetFramework: This specifies a NET Framework API version that the app is intended to run on (net48, net5.0, wp (windows phone), netcore, netcoreapp2.1, etc). Some of these are cross-platform (cross-hardware?).
RuntimeIdentifier: The runtime specifier is the cross-platform glue part of the stack and sits here in the abstraction level stack: app->framework->runtime->platform. If your library was configured for both x86 and x64, msbuild publishes the variations to bin/debug/framework/win-x86/ and bin/debug/framework/win-x64/ (so that win-x86 and win-64 and other runtimes are siblings in the output folder tree).
You must publish/build your project once (with different property values) for each runtime that you use.
To the original question, you can see that AnyCPU is a platform specifier and RIDs are runtime identifiers. The RID monikers often include x86/x64 in their names for communication convenience, but those strings do not specify the platform. Only the Platform specifier can specifier the platform.
In operation, you can specify Platform AnyCPU for building the app (indicating the app binary is appropriate for x86, x64, arm, etc., and then use a specific runtime in the publication operation (which will assign the 32/64 bitness etc. to the published binary).
My NET 5 project files require the definition of both a Platform and a TargetFramework if no MSBuild override arguments are provided. MSBuild assumes win-x64 for the runtime on my projects that define Platform=AnyCPU and TargetFramework=net5.0-windows7.0.
It's worth saying that MSBuild can get its properties from three places: the MSBuild project file; the Visual Studio dialog sheets (probably override the project file values; and the MSBuild command line (override the project file values).

C++ class dll how can be used in .net3.5 c# [duplicate]

Since I upgraded my project to visual studio 2010 project format, my C++/CLI project is targeted to .net framework 4.0.
It is easy to switch the framework version to another version from a C# project, but I have no clue how to do this in a C++/CLI project, I see no setting for this in the project property pages.
This shows up when you press F1 in the Framework and References dialog:
By default for new projects, the targeted framework is set to .NET Framework 4. The IDE does not support modifying the targeted framework, but you can change it manually.
In the project file (.vcxproj), the default targeted framework is represented by the v4.0 property element. To change the targeted framework, unload the project, use a text editor to open the project file, and then change the value of the property element from v4.0 to another version that is installed on your server. For example, if you specify v3.5, which represents the .NET Framework v3.5, Visual Studio 2008 SP1 must be installed. Save and close the file, reload the project, and verify that the targeted framework is displayed in the property page.*
That's not terribly accurate on converted projects, you'll have to add the <TargetFrameworkVersion> element yourself. Put it in the PropertyGroup labeled "Globals":
<PropertyGroup Label="Globals">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<others...>
</PropertyGroup>
The story is different when you use VS2012 and up, the first version of VS that acquired the Platform Toolset setting in the General property page. You must then select "v90" to get a proper build that targets 3.5. It is however clumsy, you must have all intermediate versions of VS installed on the machine to have that selection available.
Why you need VS2008 installed requires an explanation by itself. The core issue is that the C runtime library (msvcrt100.dll and up) contains .NET code to support managed code execution. The crucial detail is a module initializer that ensures the CRT is correctly initialized in program that uses C++/CLI code. That code always targets .NET 4 and since it is hard-baked into msvcrt100.dll (and up) you always have a rock-hard dependency on the v4.0.30319 runtime. You can only ever have a pure v2.0.50727 dependency when you use the old C runtime, msvcrt90.dll. You can only be sure that you have a msvcrt90.dll dependency when you use the compiler's #include files of VS2008.
Cold hard fact that it is pretty necessary to move to .NET 4 soon, you'll struggle with build problems like this if you don't. There are very few practical obstacles to that, .NET 4 is widely available for free on all targets you'd imagine. Overcoming the FUD that is associated with moving to a higher runtime version is generally only the real issue. No reasons for fear and doubt, it is stable.
Yes it is possible to change the target even for managed C++ projects:
Changing the Target .NET Framework for
C++/CLI (VS 2010) To change the
version of the .NET Framework for
C++/CLI projects (VS 2010)
Right click on project in Solution
Explorer and click Unload project
Right click on unloaded project in
Solution Explorer and select Edit
<projectname>.vcxproj In project XML
file locate node <PropertyGroup Label="Globals"> In that node locate
node <TargetFrameworkVersion> (if the
node cannot be found, add it) Inner
text of the node defines target
framework. It can be v2.0,v3.0, v3.5
or v4.0 Save vcxproj file and close it
Right click on unloaded project in
Solution Explorer and click Reload
Project Example
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
Note: These steps apply only for
Visual Studio 2010 as it uses new
format of C++ project files.
Source on MSDN: How to: Change the Target .NET Framework
by an anonymous user:
(Editing as I am a new user and cannot respond to this, whomever sees this feel free to submit the following) Changing the Toolset to v100 actually causes VS2010 to target .NET 4.0, even though it will still show up as targetting 3.5 in the project properties. VS2010 should really spit out a warning about this, because currently it appears as you though you can target .NET 3.5 with the v100 toolset, which you can't.
In VS 2010 if the toolset is installed go to project properties->config properties->general and change Platform Toolset from v90 to v100.

Older version of .Net not installed with latest Mono?

I've been working on a .NET 3.5 C# project using Visual Studio Community 2015, but I had always intended to do most of the development on Linux (Ubuntu Gnome 15.04) using Mono and MonoDevelop.
I'm running the latest stable Mono release (4.0.4) and MonoDevelop (5.9.6), which supports .NET 4.5 and can open the VS created solution file without issue.
Now I've been writing C++ apps on Linux for the best part of a decade, but C# and .NET are completely new to me. So I assumed that if I installed a Mono version that supports .NET 4.5, I would get .NET 3.5 as well because the later version is a superset of the older - much like a C++14 compiler supports C++03.
However this doesn't seem to be the case, as MonoDevelop states (under the Target Framework option for each project):
.NET Framework 4.5.1
Mono / .NET 4.5
Mono / .NET 3.5 (Not installed)
So do I have to install a parallel older version of Mono in order to get .NET 3.5 support, or am I just suffering a configuration problem?
No configuration issue, Mono dropped support for the older frameworks in the 4.x release. If you need to compile against the 3.5 assemblies, then yes, you will need a parallel install.
Dropped Support for Old Frameworks
Reference Assemblies
We no longer build the reference assemblies for the .NET 2.0, .NET 3.5
or .NET 4.0 APIs, we now ship binaries of the reference assemblies
(API contracts, without any actual executable code in them).
Mono will now only build the .NET 4.5 assemblies as well as the
mobile-based profiles.
Note: You can still run assemblies compiled for earlier .NET profiles
on Mono, there’s no need to recompile them (they’ll just run on the
.NET 4.5 assemblies instead).
I had a similar issue (project targeting .NET 4.0, but now only 4.5 is available through mono). My workaround was to create a symlink for 4.0:
On my Fedora 32 machine this was done by
cd /usr/lib/mono
sudo ln -s 4.5 4.0
This is supposed to work because there a (almost) no breaking changes between .NET 4 and 4.5 - YMMV
Finally, Got it to work. I'm using Visual Studio for Mac - https://www.visualstudio.com/vs/visual-studio-mac/
Under Preferences->Projects->.Net Runtimes you can change the Default .Net Runtime. It defaults to Mono 4.8.0.
This is located here on a mac : /Library/Frameworks/Mono.framework/Versions/4.8.0
From here you can download older versions of Mono https://download.mono-project.com/archive/
I downloaded 3.12.1 from https://download.mono-project.com/archive/3.12.1/macos-10-x86/
and copied it into the /Library/Frameworks/Mono.framework/Versions/ folder.
Within VisualStudio you can then add the .net framework and set it as default. My project then compiled.

Compile a .NET2.0 DLL from .NET4.0

I am using .NET4.0, but for compatability reasons, I'd like to compile to a .NET2.0 dll from c#. There should be no .NET4.0 specific functionality used in the script, so it should run fine in a .NET2.0 environment. Is there some commandline syntax on the csc that I can specify a version number with?
You mentioned csc.exe, so I'm assuming that you won't be building with Visual Studio, but rather, by command line. Also, I'm assuming that msbuild is not available on the build machine.
I believe that csc.exe is specific to each version. For example, in the folder C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319, you will find csc.exe, and in the folder C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727, you will find another version of csc.exe.
To build a .NET 2.0 dll, you should reference the csc.exe from the v2.0 folder (C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727).
Cheers!
In Visual Studio you could set the target framework version to .NET 2.0 in the properties of the project:
if you are compiling manually from the command line, can't you just run the v2 framework csc?
eg (paths from my machine)
C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe
or for v4
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe
If you build with MSBuild (which of course includes from within VS) then you can specify the target framework version from the project properties dialog. However, if you build manually it seems there is no surefire way to express that restriction.
Set the target framework to 2.0 in the project's properties. In case you are using features like LINQ that are not present on the 2.0 framework, this approach won't work. If you need full compatibility with 2.0 framework, you should write your code for the 2.0 and then compile targeting the 4.0 later if you need.

Categories

Resources