dnlib library issue when trying to reference it into other project - c#

Using VisualStudio 2013 I've successfuly compiled the latest version of dnlib which is part of the ConfuserEx and de4dot projects, the dnlib project by default targets .NET Framework 2.0 so it should be compatible to reference it in other projects that targets a greater version but when I reference the resulting dnlib.dll in a new project that targets a .NET framework greater than 3.0 the project can't compile.
There is any compiling error information just a VisualStudio messagebox that says:
There were build errors. Would you like to continue and run the last
successful build?
I've tried the dnlib.dll in a (new, empty) WinForms project using both the debug and the release version of dnlib.dll, I've tried targeting FW 3.5, 4.0, 4.5 and 4.5.1 but the project has been compiled successfuly only targeting FW 2.0 and 3.0.
By the other hand, I'm totally able to navigate through the library members and instance the classes inside and all that, but no way to compile a project with that referenced dnlib.dll.
I think that if the default FW targeting in the dnlib project is 2.0 should be for a good reason 'cause it touchs external assemblies and that, so I'm not sure to try to solve this issue by increasing the FW targeting in the dnlib project, but anyways I've tried to increase it to 4.0 to see what hapens and I get a lot of compiler errors about type defs in mscorlib.dll.
I'm missing something?
How I can solve this problem to be able to compile a project that targets FW4.0 with the dnlib.dll that targets FW2.0 referenced?

Ok, fiddling around, I could get some Warnings but not errors. As per MSDN, ExtensionAttribute came into being with Net 3.0 and HandleProcessCorruptedStateExceptionsAttribute with NET 4.0. So, in order to make the NET 2.0 code compatible with 4.0 projects, it provides the missing Attributes. The warnings are just that they are multiply defined, and since they are just Attributes, I don't think it matters.
Rather than comment them out, there are 2 easy ways to get rid of the Warnings.
Method 1 (better, I think): Create solutions for Net 2.0 and 4.0 builds.
Open the basic Net 2.0 solution. Select the Solution (dnlib) in Solution Explorer. On the File menu pick Save dnlib.sln As and use dnlib20.sln as the file name. This is your NET 2.0 FrameWork Solution.
Do Save As again, this time to dblib40.sln. This will be your Net 4.0 Framwwork solution in a moment. Switch both the console test project and dnlib library projects to Net 4.0 Target platform. Then, in Solution Explorer, exclude the last 2 files from the solution: HandleProcessCorruptedStateExceptionsAttribute.cs and ExtensionAttribute.cs. Save it, clean and build, and you should be good.
You don't need these 2 files because NET has them defined (which is the warning); they are only meant for 2.0 projects/solutions.
Note: You can also set it up so that the solutions compile to their own folders, so you dont get them confused. On the Build Tab, next output add a folder(..\Debug\bin\Net20 and ..\Debug\bin\Net40). You'll have to change/update for both Debug and Release versions.
Method 2: Define some conditional compiler constants.
Create dblib20.sln and dblib40.sln solutions as above (unless you dont want to even use 2.0). Be sure to set the Framework to NET 4 in the 4.0 solution.
In the Net 2.0 dnlib project file, go to Project Properties --> Build --> General add the conditional compile symbol NET20. Now, in HandleProcessCorruptedStateExceptionsAttribute.cs wrap the code there in a #if:
#if NET20
using System;
#pragma warning disable 1591 // XML doc warning
namespace System.Runtime.ExceptionServices {
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
sealed class HandleProcessCorruptedStateExceptionsAttribute : Attribute {
}
}
#endif
In ExtensionAttribute.cs, do the same thing. Then Clean and Rebuild, and all should be well. Since the symbol is only defined in the NET20 solution, those classes will only be compiled when you use/open the Net 2.0 solution. If you download another update, you will have to redo this unless they provide a NET 4.0 solution file.
AFAIK, there still are not any built in FrameWork constants.
Finally, when those warnings are cleared away, there are 5 compare warnings, but from the looks of it, those can be ignored (the code seems to be doing what it wants).

This worked for me:
Change dnlib project's target version to .NET 4.0 Framework Client Profile.
Change the Example project target version to .NET 4.0 Framework Client Profile.
Remove/comment out ExtensionAttribute in ExtensionAttribute.cs in dnlib
Remove/comment out HandleProcessCorruptedStateExceptionsAttribute in dnlib
I then compiled and got no errors.
I used Visual Studio 2012.

Related

TargetFrameworks in .NET Core

We are upgrading our project to .NET 6 from .NET Framework 4.5. We have a windows form application. Many of windows form commands has been depriciated in .NET 6. So to tackle this, I changed one of the Windows Forms project in the solution from:
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
</PropertyGroup>
to
<PropertyGroup>
<TargetFrameworks>net45;net6.0-windows</TargetFrameworks>
</PropertyGroup>
Now after changing this, I get the below error:
Project <another_project> targets 'net6.0-windows'. It cannot be referenced by a project that targets '.NETFramework,Version=v4.7.2'.
I understand why another_project is throwing this error message which is because the another_project is referenced in this Windows Form project and another_project's TargetFramework is .NET 6. So, I can change the TargetFramework for another_project to include .NET 4.5 as well.
But my question is, if I change this TargetFramework to TargetFrameworks and add multiple Framework there, does that mean my project is not upgrading to .NET 6 completely. Since it's using .net45 to complie/build in those cases, where it's failing to build in .NET 6. How does TargetFrameworks work??
I found the below link also, TargetFramework vs. TargetFrameworks (plural). But was not much helpful to understand this.
I'm assuming that you've upgraded your project files to SDK-style.
<TargetFrameworks>net45;net6.0-windows</TargetFrameworks> will effectively build your project twice - once for .NET 6.0 and once for .NET Framework 4.5.
(I'm not sure why your .NET Framework project is still targeting .NET 4.5 - I would have thought you should have retargeted it to 4.8 a long time ago...)
The output folders for these two targets will be:
For the DEBUG build:
\bin\Debug\net6.0-windows
\bin\Debug\net48
For the RELEASE build:
\bin\Release\net6.0-windows
\bin\Release\net48
Now if you want to reference one of those assemblies in another project, you're going to need to decide which to use, depending on the target framework for the dependent project.
In your case, it seems that you should be referencing the one in the "net6.0-windows" folder, so you should change your other project to reference that.
However, if you want the dependent project to ALSO be multi-targeted, you will need to change the hint path in the dependent project to use a compile variable to select the correct one.
For example, suppose your multi-targeted dependent project currently references a DLL using the following hint path:
<Reference Include="YourLibraryName">
path to referenced dll\bin\debug\net45\YourLibrary.dll
</Reference>
(Where "path to referenced dll" is whatever path is needed to locate the library.)
Clearly that will only reference the DEBUG Net 4.5 version of the library. You want it to reference the correct debug or release version and the correct .Net 4.5 or .Net 6.0 version. To do that, you can change the hint path to:
<path to referenced dll>\bin\$(Configuration)\$(TargetFramework)\YourLibrary.dll
At build time, $(Configuration) is replaced with the correct DEBUG or RELEASE string, depending on whether you're building DEBUG or RELEASE.
Similarly, the $(TargetFramework) will be replaced with the current build target, taken from the <TargetFrameworks>net45;net6.0-windows</TargetFrameworks> setting - either "net45" or "net6.0-windows".
Doing this will cause the correct DLL to be chosen from your multi-targeted project on which this project depends.
Note that this only applies to references using HintPath as above. If you're using project references, things would be different.
Also note that it's also possible (and maybe better) to create a NuGet package which will handle the dependencies etc properly, but that's a whole different story.
TargetFrameworks is used to build same project to multiple frameworks (so you have binary for each of them in output). It's usually used by libraries so they can be consumed by app targeted for different frameworks or, much less frequently, by apps, so they could be run on different machines.
I guess neither of theses is your cases. You just need to rework your app so it uses only features available in .NET Core.
Since you have added both net45 and net6.0-windows to your project it means that it should be compliable for both frameworks (i.e. it will be compiled twice, for each of the target frameworks), but you are trying to add reference to net6.0 project, which can't be used from net45. You need to either upgrade both to net6.0 only, or add net45 to the another_project.
Though usually it is another way around (compared to what you are trying to do), you use multitargeting for library projects (i.e. another_project in this case if I understand correctly) and keep one version for the executables (i.e. WinForms project should keep it's version).

Compiler refuses to compile after I retarget a .NET 6 project to .NET Framework 4.8

I have a .NET 6 project. I want to retarget it to .NET 4.8. I did it from the project properties. I removed all instances of my code using newer language features. I have clean the solution also
However after doing it, I get an error while compiling
CS8630 Invalid 'nullable' value: 'Enable' for C# 7.3. Please use language version '8.0' or greater
at line 1, from a file called CSC in my project folder (weird, CSC is the name of the compiler, and I have no such file). I am not using nullable types surely and this error is not correct IMO. What do I do?
EDIT: #RahulSharma's answer isn't valid. It doesn't work, produces another error.
This error is shown when your project settings reference the language version 7.3. I assume you can verify this by right-clicking your project & choose properties, build, advanced in VS. If the language version is shown as 7.3, you need to change this so it match the framework version you use. Howver you cannot change this in the VS dialogue, so you need to do this manually.
Unload your project and open the project file as a file, and then add the <LangVersion>latest</LangVersion> in the <PropertyGroup> section.
See the full documentation of language versions for each .NET framework version here

Class library references on Visual Studio 2015

I've added a new Class Library (Package) project to my solution. It's my first experience with a .NET Core (or whatever I'm using, still confused)
My class library contains two references: .NET Framework 4.5.1 and .NET Platform 5.4
I'm trying to import some code from a sample project that uses IPrincipal. For some reason it's saying that it doesn't exist on namespace "System.Security" altohugh I can get it trough intellisense.
What's wrong with my project settings?
The new feature of .NET Core and Class Library (Package) is that it targets multiple platform and will compile into multiple assemblies which get automatically packaged into a nuget package.
When your class library targets multiple targets, it will compile to all of them. So if a certain library is only available on full .NET framework but not on .NET Core or other target framework, then you may receive intellisense if your editor is set to .NET 4.5. More information can be found in my other recent answer.
You can switch back and forth with the pull down menu on top left of the coding window, show in the screenshot below.
If you do not want to target a certain framework, you have to remove it's moniker from the project.json file or use preprocessor directives to write platform specific code or libraries/replacements.
.NET Core is heavily modularized and most of only the core modules are referenced in the default project and if you need additional one you need to reference them within the dotnet5.x section.
Basically you have multiple places with "dependencies" in your project.json, a global one where you can add dependencies which are available on all targeted frameworks and one within each "frameworks" section for each of the targets only.
Though the other answer covers some basic concepts, it would require some attention on which classes are available and which are not.
Microsoft temporarily host a web site at http://packagesearch.azurewebsites.net to assist.
If you can find a suitable package for RC1 from there, then you can add it to your project.json file. If not, you will have to conditional compile it to a desktop profile or use other alternatives.

Downgrading MSbuild file from 4.0 to 3.5

I've got a heap of csproj files that were created with Visual Studio 2010 and targeted .NET 4.0.
I am now trying to compile on Mono 2.6.7 with xbuild, however 2.6.7 can't compile verison 4 msbuild projects. (2.10.1 has no issues, which is what we've been using, but I want to do an experiment on 2.6.7).
Using MonoDevelop I've changed the Runtime Version to Mono / .NET 3.5, and it compiles fine under 2.6.7. Changing to use xbuild however fails.
What steps are required to change the MSBuild version to 3.5? The top line in the csproj file is pretty obvious:
<Project ToolsVersion="4.0"
And changing that is easy, but I'm concerned there are less obvious things that should also be changed.
Anyone know the definitive way to downgrade from a 4.0 to 3.5 msbuild file?
I don't know of an authoritative guide, but having done this several times I can say what I know.
For a simple Class Library or WinForms application, it's pretty straight forward:
The ToolsVersion on the project file needs to be set to 3.5, as you indicated.
If there is an OldToolsVersion element (meaning it was previously upgraded) in the project file, it should be removed. The same goes for FileUpgradeFlags and UpgradeBackupLocation elements. Basically, you don't want the OldToolsVersion to be the same as the current version.
If you were using the Client Framework profile, in 3.5 the element is called TargetFrameworkSubset. In 4.0, it's called TargetFrameworkProfile, so the element should be renamed. (Not sure of the applicability to Mono on this one).
Using MonoDevelop, Project->Export the solution to VS2008 format.
Are you sure you have to downgrade the MSBuild version? Just compile with 2.10, switch your environment to 2.6.7, and run the tests.

MSBuild 4 fails to build VS2008 csproj due to 1 compiler warning

We have a VS2008 CS DLL project targeting .NET 3.5. It builds successfully on our CI server when using MSBuild 3.5.
When CI is upgraded to use MSBuild 4.0, the same project fails to build, due to 1 warning message:
c:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets(1418,9):
warning MSB3283: Cannot find wrapper
assembly for type library "ADODB".
The warning does not occur with MSBuild 3.5, and I'm surprised that it results in Build FAILED. We do not have the project set to treat warnings as errors.
All our other projects build successfully with either version of MSBuild.
The error message was not telling the whole story. The ADODB assembly on our dev machines is loaded in the GAC. That was not the case on the CI build machine.
The reference to ADODB was only placed into our C# project by a TLBIMP pre-build task, within the C# project (along with references to MSXML and VBA dlls). The latter DLLs are included in our source code repository, and thus found during the CI build process. ADODB is not. However, we also discovered that we could safely remove from the C# project all the added references, including the one to ADODB.DLL.
This fixed the problem. (Thanks for your suggestions -- they kept me thinking till we got there.)
Try either removing any hardwired toolsversion in your msbuild (and csproj) files, or setting them to ToolsVersion="4.0".
Read: http://msdn.microsoft.com/en-us/library/bb383796.aspx for a better understanding of the significance of the attribute.
Since you want to target 3.5, make sure you have the target framework version set up correctly by checking that the TargetFrameworkVersion in your csproj.
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
If you set the ToolsVersion to 4.0, any machine that wants to build the project, will have a dependency on the 4.0 framework (which has the 4.0 msbuild), even though you're targetting 3.5.
If you're targetting 3.5, and your projects are VS2008, there's no need to use msbuild 4.0 over msbuild 3.5 (they can exist peacefully side by side). Just using the 3.5 msbuild would be the simpler solution.
This is a ClickOnce issue. Remove that dependency from the list.
BTW, this bug is present in VS2008 too, but seems to not have triggered for you.

Categories