I'm in C# in Visual Studio running 2015 Update 3.
I'm using a dll that I made myself for the backend of a system, and in the references of the project, one shows the "System" as Version 2.0.5 and the project being used as a dll shows it as 4.0.0. I believe this is the cause of a conflict that is preventing me from running this app. How do I update just the system version or even specify it so I can make them the same?
I think you should go to the references of your project containing the old reference, remove System and add it with version 4.0.0.0. However, you should also check that target .NET framework versions match (maybe the older dll is obtained compiling against .NET framework 2.0 and the newest one against .NET framework 4.0).
In order to find out the cause that is preventing you from running the application (you should provide what is happening), an useful tool is Assembly Binding Log Viewer which will show the exact assemblies that the application is trying to load (fully qualified assembly names).
Related
I have a vsix project. I use commandtool and create files. I upgraded .net framework (4.6.1 to 4.7.2) and packages
I run project, everything is ok. But I get error when I click Extension's button.
I checked error in XML file. Error description is
Description: Could not load file or assembly Microsoft.VisualStudio.Threading, Version=16.8.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; or one of its dependencies
But there is package in References
Do you have any idea?
Best Regards
When you upgraded to the newer version of Microsoft.VisualStudio.Threading, you upgraded to a version that's higher than what your Visual Studio is shipping with as a part of the platform. Although there are ways you could make your version now be the preferred version, the easiest answer is probably 'don't do that', since you're artificially limiting which versions of VS your extension could install onto.
Unless you had a specific reason to upgrade, you're probably best off leaving the version there.
From the .NET APIs catalog, I understand that the Microsoft.Win32.Registry class is declared in the .NET Standard + Platform Extensions 2.0 package in an assembly Microsoft.Win32.Registry, Version=4.1.1.0, PublicKeyToken=b03f5f7f11d50a3a.
I've created a class library which targets .NET Standard 2.0, and here's a simple class:
public class NetStandardClass
{
public string GetHklmRegValue()
{
var lmKey = Microsoft.Win32.Registry.LocalMachine;
var softwareKey = lmKey.OpenSubKey("Software");
return "value";
}
}
I've created a .NET Framework 4.7.2 console application which references my above class library:
class Program
{
static void Main(string[] args)
{
string value = new ClassLibrary2.NetStandardClass().GetHklmRegValue();
}
}
When I run this on Windows, this throws a run-time exception:
System.IO.FileNotFoundException: 'Could not load file or assembly
'Microsoft.Win32.Registry, Version=4.1.3.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The
system cannot find the file specified.'
Based on what I've read, having assembly load issues in this scenario is somewhat of a known issue. The prescribed work-around is to enable automatic binding redirects and make sure my .NET Framework application is using PackageReference rather than Project.Config. I have done this with my projects from which I shared the above code, but I'm still getting the error. What confuses me most, though, is that the error is indicating the .NET Core / .NET Core + Platform Extensions assembly (Version=4.1.3.0, PublicKeyToken=b03f5f7f11d50a3a) rather than the .NET Standard (Version=4.1.1.0, PublicKeyToken=b03f5f7f11d50a3a) or .NET Framework (Version=4.0.0.0, PublicKeyToken=b77a5c561934e089) versions from the APIs catalog:
This is further corroborated by the Microsoft.Win32.Registry.DLL that is in the output directory:
Based on further reading, I can make a little progress by doing either of the following:
Add <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> to the .NET Standard class library proj file
-- or --
Add the Microsoft.Win32.Registry NuGet package directly to my .NET Framework console application.
Either of these results in loading some version of the assembly, but then I get some odd behavior: I get an NRE for the LocalMachine property, which shouldn't happen.
So here are the questions:
1.) Since my project is a .NET Framework application, why is it not using the Microsoft.Win32.Registry class in the .NET Framework API, specifically the mscorlib assembly that the same APIs catalog refers to?
2.) Why isn't the "work around" in the GitHub post not working for me?
3.) Why is it seemingly looking for the .NET Core / ... extensions version of the assembly?
4.) Why when I explicitly export the NuGet Microsoft.Win32.Registry assembly in the .NET Standard class library or directly reference the package in the .NET Framework console application does it result in the strange behavior where Microsoft.Win32.Registry.LocalMachine is null, which should never be the case on a Windows machine?
The following answers make an assumption of having the newest version of Visual Studio 2019 (v16.4.3 at time of writing) installed, as this may have some effect on the outcome.
Question 1):
1.) Since my project is a .NET Framework application, why is it not using the Microsoft.Win32.Registry class in the .NET Framework API, specifically the mscorlib assembly that the same APIs catalog refers to?
This will actually use the v4.0.0.0 mscorlib Registry class when the projects are set up in either of the following manners:
Option 1
Class library: Target Framework = netstandard2.0, NuGet packages = Microsoft.Windows.Registry (v4.5.0)
Console app: Target Framework = net472, NuGet is set to "packages.config" mode, NuGet packages = Microsoft.Windows.Registry (v4.5.0) [and also AccessControls and Principal.Windows, as they are dependencies]
NOTE: Here, if you don't add the Microsoft.Windows.Registry package, you typically will get the runtime error looking for version 4.1.1.0 of the Registry dll. But I believe the version it looks for is based on what the current .NET Core SDK version you have installed.
Option 2 [I think this is the one you really want]
Class library: Target Framework = netstandard2.0, NuGet packages = Microsoft.Windows.Registry (v4.5.0)
Console app: Target Framework = net472, NuGet is set to "PackageReference" mode, NuGet packages = None
NOTE: In VS2019, if you have the option for "Allow format selection on first package install" checked, then it will allow you to choose to use the PackageReference style, where NuGet packages are referenced in the project file instead of packages.config. Typically you have to install any one NuGet package just to set this mode, but afterward can uninstall that package and it will stay in that mode. I believe you could also set the default mode as well, before you first create your net472 project.
NOTE: Here, the PackageReference mode seems to help resolve the NuGet dependencies on the other .NET Standard 2.0 class library, where as the package.config mode requires you to do it yourself it seems.
This should be easily reproducible, however, things that can cause some sort issue can be any of:
- older versions of VS2019 being used
- skipping binding redirects setting turned on for NuGet in VS
- auto binding redirects turned off for the .NET 4.7.2 project
- not "rebuilding" the solution after package or reference changes
- not restarting the computer after installing/updating .NET SDK's or VS2019 updates
- still having a packages.config file
I'd also like to note that in Option 1 above, I found in testing this out that if you don't add the Microsoft.Windows.Registry package, it fails on runtime looking for version 4.1.1.0 of the registry dll. But, I was able to get it to fail looking for runtime 4.1.3.0 by first installing Microsoft.Windows.Registry 4.7.0, and then I uninstalled it (thereby leaving the two dependent packages AccessControl and Principal.Windows), and without rebuilding the project: if I run it, it fails on runtime with the 4.1.3.0 version being the one it's looking for. Rebuilding it reverts back to 4.1.1.0. This remains the same even if I remove the two dependent packages. Note: this also works if you simply remove the references to the dll's in the project, rather than uninstalling the NuGet packages.
Question 2):
2.) Why isn't the "work around" in the GitHub post not working for me?
I have a feeling this is happening because you may have an older version of VS2019 than 16.4.3. I found that when I was using an older version, the PackageReference mode still resulted in the runtime error. When I updated (sorry, I am not sure which exact revision actually fixes it) VS2019 to 16.4.3, this seems to now just work. I am not sure if this is some sort of unexpected interaction with the various SDK's (perhaps some being more recently released but not supported by an older revision of VS). It could also be an issue if the packages.config file is still lingering around.
Another issue could potentially be interference by other NuGet packages that may be installed and have different library version requirements.
Question 3):
3.) Why is it seemingly looking for the .NET Core / ... extensions version of the assembly?
In a .NET 4.7.2 project that references a .NET Standard 2.0 (.NET standard projects are .NET Core projects by default), it will utilize the .NET Core framework, not the .NET framework. So any references to the Registry are not by default available. You need the Microsoft.Windows.Registry packages (at the least) to allow use of the Registry, which I believe has the ability to act as a shim to the .NET 4.7.2 mscorlib verison of the library if available, but use the 4.1.1.0 version as a fallback (or 4.1.3.0 version if you're referencing from a .NET Core project instead).
Question 4):
4.) Why when I explicitly export the NuGet Microsoft.Win32.Registry assembly in the .NET Standard class library or directly reference the
package in the .NET Framework console application does it result in
the strange behavior where Microsoft.Win32.Registry.LocalMachine is
null, which should never be the case on a Windows machine?
I haven't personally tested this, and didn't run into this issue when I tested the above, but my feeling on this is that the dll's are likely missing their dependent dll's. But thinking about that further, would likely just result in another runtime error if that's the case. I think the issue is that they aren't intended to be directly exported and something may be missing along the way.
I'd also note that if you run this on any platform other than Windows, the registry is likely to come back as null since I think it wouldn't exist on, say, a Linux runtime.
Other Notes:
I get a general sense that this sort of thing has been a little buggy with VS and .NET Core in general referencing to/from .NET Framework, and that there's progress being made regularly to improve this.
I found also that there are some surprising issues I ran into that I didn't expect. For example, creating a .NET Standard console app, referencing the .NET Standard class library, and still getting the runtime error, no matter what packages I installed on the console app. You would think the exact same target framework would just work without any special configurations, but it doesn't seem to. But if you create a .NET Core console app instead, it does work properly. It's a bit mystifying, but there's always a technical explanation somewhere in the mix.
I have made a setup of Visual studio to compile C# code in my Ubuntu Machine .
I loaded the workspace/my code to VS and I could see the below error.
The reference assemblies for framework ".NETFramework,Version=v4.5" were not found. To resolve this, install the SDK or Targeting Pack for this framework version or retarget your application to a version of the framework for which you have the SDK or Targeting Pack installed. Note that assemblies will be resolved from the Global Assembly Cache (GAC) and will be used in place of reference assemblies. Therefore your assembly may not be correctly targeted for the framework you intend.
Please help me on resolving this issue as am a beginner in Visual studio.
Thanks
If project is heavy, you can follow
this procedure
If your project is lightweight, create a new .netcore project using VS and move your code (and dependencies references)into that new project. then let VS telling you potential errors and correct them.
Looking at the procedure, you can firstly retargeting your actual project in dotnet 4.6.2 framework in order to "ensures that you can use API alternatives for .NET Framework-specific targets in the cases where .NET Core can't support a particular API."
I would recommend running the portability tool in Visual Studio 2017 if you have it. This will give you an idea if you will have a hard time moving it over.
As for your error with the csproj, that's because that file has paths within it, which are pointing to locations using windows paths, instead of Linux paths.
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.
I have solution with mixed projects: C#, native C++ and CLR/C++ (this also requires some external DLLs). When I used default settings of VS 2012 and targeted for .Net 4.5 it worked fine. But then I had to downgrade it to .Net 4.0.
I succeed by building solution only for 32-bit and forcing C# main project to be built for 32-bit also (usually C# is used for "Any CPU").
With such settings in runs fine on 2 computers out of 3 I have for tests -- meaning on it fails. It claims it cannot load CLR/C++ project or one of it dependencies.
So my problem is how to run it or at least to know what failed exactly? From the list of installed programs I can see that on working computer I have either .Net 4.5 Multi-Target or I don't have .Net 4.5 at all (only 4.0). On computer which fails I have .Net 4.5 (period). So maybe my program tries to load some assemblies from .Net 4.5 instead of 4.0? But that is just guessing.
Question -- how to diagnose such twisted solution and how to fix it?
Install .Net framework 4.0 multi-targeting pack
Check references (including NuGet, if any)
When I encounter a similar problem I usualy check the following:
Do you have Visual Studio installed on any of those three machines? I guess it's installed on the two where your application is running. If so, I'll extend the list later.
Check the target of the C++/CLI project - it should be Win32 if you build for 32-bit.
Run the application without Visual Studio, wait until it fails and go to the Event Viewer to look for some usefull information there.
Get Process Monitor, run the application without Visual Studio, wait until it fails, stop monitoring and filter the list by the application name and failed operations and look there for some usefull information.