Having the code below in VisualStudio 2017 .NET Core 2.0 Console App
using System;
using System.Security.Principal;
namespace smallTests
{
class Program
{
static void Main(string[] args)
{
var identity = WindowsIdentity.GetCurrent();
}
}
}
Why am I getting the error:
The name 'WindowsIdentity' does not exist in the current context
If I can see this class in .NET Core 2.0 library in .Net Core docs ?
Same code works in .NET Console app.
[EDIT]
#Will #JohnnyL Commented that I do not refer, System.Security.Principal.Windows.dll, that is true.
But I am curious why it is not working, because
in .NET 4.6.1 project (where class WindowsIdentity is visible) I also do not refer this System.Security.Principal.Windows.dll specifically. However i refer System.dll.
I always thought that it works like namespace hierarchy. For instance, when I refer to
System.Security.Principal.dll
i can use class which is in
System.Security.Principal.Windows.dll.
Am I wrong?
I added System.Security.Principal.dll to .NetCore solution by hand but it still does not work.
[EDIT2]
#Will Thank you a lot for expaining the subject it helped me a lot.
I tried to figure out is WindowsIdentity compatible with Core and it seems that it is please see:
in this apisof.net in Declarations area i can see that WindowsIdentity is in .Net Core 2.0 System.Security.Principal.Windows, Version=4.1.1.0, PublicKeyToken=b03f5f7f11d50a3a
but i do not have System.Security.Principal.Windows.dll in references, should I add it? If yes from where?
in .NET Core api reference i see this class in the list (what is the purpose of that listing if it is not compatible with core?
I also find information about that class in that link
Am I looking in wrong places?
Microsoft announced Windows Compatibility Pack for .NET Core a few weeks ago,
https://blogs.msdn.microsoft.com/dotnet/2017/11/16/announcing-the-windows-compatibility-pack-for-net-core/
And by analyzing the source code of System.Security.Principal.Windows.csproj and the commit adding it,
https://github.com/dotnet/corefx/blob/master/src/System.Security.Principal.Windows/src/System.Security.Principal.Windows.csproj
My conclusion is that this is also part of the Windows only compatibility libraries, so can only be used on Windows.
To add that to your project, open your csproj and add a PackageReference tag for System.Security.Principal.Windows manually (or use Visual Studio's NuGet Package Manager).
We've got a .NET Framework .dll that we're porting to .NET Core. Currently we're inheriting from ConfigurationElement and ConfigurationSection from System.Configuration to create custom configuration sections in the app.config (or it's .NET Core equivalent)
Questions:
It appears the .NET Core way is Microsoft.Extensions.Configuration. Is that correct? Because it lives on ASP.NET Core's github project instead of .NET Core's github project. We have no ASP parts.
If so, any .NET Core examples on creating and loading custom configuration sections not relying on startup.cs ? Ideally we'd like to read from a text source (XML or JSON) directly into a POCO object graph for strongly typed benefits.
With .NET Core 2.0, will there be any support for the traditional ConfigurationElement and ConfigurationSection negating the need for any such porting efforts to begin with ? Reason I ask is the .NET Core 2.0 Roadmap says
.NET Core gain over 5,000 APIs from .NET Framework as part of this work making it a broader platform.
I am not aware of app.config and System.Configuration support in .NET Core. Probably, no, but that's just a guess. You can setup configuration for .NET Core application in Main method:
class Program
{
static void Main(string[] args)
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var poco = new Poco();
configuration.Bind(poco);
Console.WriteLine(poco);
Console.ReadKey();
}
}
class Poco
{
public bool Enabled { get; set; }
public Sort Sort { get; set; }
public override string ToString()
{
return $"Enabled={Enabled}, SortOrder={Sort.Order}";
}
}
class Sort
{
public int Order { get; set; }
}
appsettings.json is following:
{
"enabled": true,
"sort": {
"order": 2
}
}
Outputs:
Enabled=True, SortOrder=2
You need to reference Microsoft.Extensions.Configuration.Json and Microsoft.Extensions.Configuration.Binder packages.
No dependency on ASP.NET Core.
Microsoft.Extensions.Configuration is quite extensible, it can use different settings providers like environment variables, command line arguments, etc. So it is possible to implement custom provider for ConfigurationSection-like configuration if needed.
Based on this comment they are not going to bring System.Configuration to NetStandard 2.0.
With the dust settling down from .NET Standard 2.0 release it is possible to use your usual System.Configuration even in .NET Core 2.0 on Linux!
Here is a test example:
Created a .NET Standard 2.0 Library (say MyLib.dll)
Added the NuGet package System.Configuration.ConfigurationManager v4.4.0. This is needed since this package isn't covered by the meta-package NetStandard.Library v2.0.0
All your C# classes derived from ConfigurationSection or ConfigurationElement go into MyLib.dll. For example MyClass.cs derives from ConfigurationSection and MyAccount.cs derives from ConfigurationElement. Implementation details are outof scope here but Google is your friend
Create a .NET Core 2.0 app (e.g. a console app, MyApp.dll). .NET Core apps end with .dll rather than .exe in Framework.
Create an app.config in MyApp with your custom configuration sections. This should obviously match your class designs in #3 above. For example:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="myCustomConfig" type="MyNamespace.MyClass, MyLib" />
</configSections>
<myCustomConfig>
<myAccount id="007" />
</myCustomConfig>
</configuration>
That's it - you'll find that the app.config is parsed properly within MyApp and your existing code within MyLib works just fine. Don't forget to run dotnet restore if you switch platforms from Windows (dev) to Linux (test).
Besides described way of migration to Microsoft.Extensions.Configuration (which totally makes sense) as it should (at least I hope) be possible to use the same types from System.Configuration on .NET Core 2.
Here's System.Configuration types in corefx:
https://github.com/dotnet/corefx/tree/master/src/System.Configuration.ConfigurationManager
I can't tell you that they are fully compatible with the ones from full .NET. But at least it's something that takes us a hope )
So it looks like .NET Core 2 will have that old System.Configuration stuff but not netstandard2. Probably it's because MS doesn't want to share these types among other platforms (Xamarin).
I'm developing a library for use with WPF and Windows 10. I'm running into issues getting it to compile on the latter. Here is some of the code:
project.json
{
"frameworks": {
"net46": {
"frameworkAssemblies": {
"WindowsBase": "4.0.0.0"
}
},
"netcore50": {
"dependencies": {
"Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
}
}
}
}
Dependency.cs
using System;
using System.Collections.Generic;
#if NET46
using System.Windows; // .NET Framework 4.6
#elif NETCORE50
using Windows.UI.Xaml; // Windows 10 apps
#endif
public static class Dependency
{
public static DependencyProperty Register<T, TOwner>(string name, PropertyChangedCallback<T, TOwner> callback)
where TOwner : DependencyObject
{
// Code here....
}
}
While this compiles fine for net46 (which is the traditional .NET Framework), I'm having trouble getting it to work for netcore50 (which can be used by Windows 10 apps). For some reason, it looks like types like DependencyProperty or DependencyObject are not included in that configuration.
Is there a netcore50-compatible NuGet package I can install that contains these types, so I can use them from my library?
Thanks for helping.
EDIT: I just typed in DependencyProperty in VS and hit F12. It appears that the type lives in the Windows.Foundation.UniversalApiContract assembly, but there's no such package on NuGet.
Finally solved the problem on my own! (If you're looking for a quick answer, you may want to scroll down.)
I remembered by chance that the .NET Core GitHub repo had a bunch of WinRT-specific libraries, like System.Runtime.WindowsRuntime. So, I headed over there to see how they did it.
It appears they use some kind of internally-hosted "targeting pack", which contains a single Windows.winmd file (which holds all the types in the Windows Runtime), to achieve this affect. Unfortunately, the package is hosted on a private NuGet feed meant only for the .NET Core team, so I can't use it.
I've opened an issue about this on the CoreFX repo here, so I can petition Microsoft for an official solution to this problem. In the meantime, I've taken matters into my own hands. I've found all the different versions of Windows.winmd on my laptop, and uploaded them as NuGet packages. Here they are:
Target.Windows
Target.WindowsPhone
Target.WindowsRuntime
You can use them like this:
"frameworks": {
".NETPortable,Version=v4.5,Profile=Profile32": {
"dependencies": {
"Target.WindowsRuntime": "8.1.2"
}
}
}
After that, you'll be able to write something like this:
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
public class MyApp : Application
{
public MyApp()
{
var button = new Button();
button.Content = "Hello, world!";
}
}
and it'll just work.
With .NET Core 3 and up (now in preview) there is a package you can install that includes most WinRT classes Microsoft.Windows.SDK.Contracts
WPF Isn't compatible with .net Core nor are W10 Universal Apps, to my knowledge only Console apps and web apps are currently compatible with .net core, you should be able to still use the the new code base with the new project system but you will need to remove .net core from your configuration in order to compile
if you want to use .net core with linux with a desktop app you will simply have to wait, or use a compatible windowed app framework ( if any are available yet), you should be able to use a cross platform framework base around html/js such as Electron or Cordova ( not sure on this one on whether there is a desktop app framework with Cordova)
Here's a concrete example of what I want to do.
Consider the string.Join function. Pre-.NET 4.0, there were only two overloads, both of which required a string[] parameter.
As of .NET 4.0, there are new overloads taking more flexible parameter types, including IEnumerable<string>.
I have a library which includes a Join function that does essentially what the .NET 4.0 string.Join function does. I was just wondering if I could make this function's implementation dependent on the .NET framework being targeted. If 4.0, it could simply call string.Join internally. If 3.5 or older, it could call its own internal implementation.
Does this idea make sense?
If it does make sense, what's the most logical way to do it? I guess I'm just assuming a preprocessor directive would make the most sense, since a call to string.Join with an IEnumerable<string> parameter won't even compile when targeting a .NET version older than 4.0; so whatever approach I use would have to take place prior to compilation. (Checking the Environment.Version property at runtime, for example, wouldn't work.)
You can take a look at another question on Stack Overflow that illustrates how to set conditional constants through the project file's XML:
Detect target framework version at compile time
Then using that you can determine if you should use the .NET 4 overloads or your own library.
At some point (not sure when), Microsoft added predefined symbols for .NET versions into the MSBuild build system. Everything here works if you are using MSBuild from the .NET 5+ SDK (even if the project you are building with that SDK is using a much older target framework).
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives
Target Frameworks
Symbols
Additional symbols available in .NET 5+ SDK
.NET Framework
NETFRAMEWORK, NET48, NET472, NET471, NET47, NET462, NET461, NET46, NET452, NET451, NET45, NET40, NET35, NET20
NET48_OR_GREATER, NET472_OR_GREATER, NET471_OR_GREATER, NET47_OR_GREATER, NET462_OR_GREATER, NET461_OR_GREATER, NET46_OR_GREATER, NET452_OR_GREATER, NET451_OR_GREATER, NET45_OR_GREATER, NET40_OR_GREATER, NET35_OR_GREATER, NET20_OR_GREATER
.NET Standard
NETSTANDARD, NETSTANDARD2_1, NETSTANDARD2_0, NETSTANDARD1_6, NETSTANDARD1_5, NETSTANDARD1_4, NETSTANDARD1_3, NETSTANDARD1_2, NETSTANDARD1_1, NETSTANDARD1_0
NETSTANDARD2_1_OR_GREATER, NETSTANDARD2_0_OR_GREATER, NETSTANDARD1_6_OR_GREATER, NETSTANDARD1_5_OR_GREATER, NETSTANDARD1_4_OR_GREATER, NETSTANDARD1_3_OR_GREATER, NETSTANDARD1_2_OR_GREATER, NETSTANDARD1_1_OR_GREATER, NETSTANDARD1_0_OR_GREATER
.NET 5+ (and .NET Core)
NET, NET6_0, NET5_0, NETCOREAPP, NETCOREAPP3_1, NETCOREAPP3_0, NETCOREAPP2_2, NETCOREAPP2_1, NETCOREAPP2_0, NETCOREAPP1_1, NETCOREAPP1_0
NET6_0_OR_GREATER, NET5_0_OR_GREATER, NETCOREAPP3_1_OR_GREATER, NETCOREAPP3_0_OR_GREATER, NETCOREAPP2_2_OR_GREATER, NETCOREAPP2_1_OR_GREATER, NETCOREAPP2_0_OR_GREATER, NETCOREAPP1_1_OR_GREATER, NETCOREAPP1_0_OR_GREATER
This allows you to, for example, do this:
#if NET5_0_OR_GREATER
Console.WriteLine("This is .NET 5 or later.");
#elif NETCOREAPP
Console.WriteLine("This is an older version of .NET Core.");
#elif NETFRAMEWORK
Console.WriteLine("This is the legacy .NET Framework.");
#else
Console.WriteLine("This is something else.");
#endif
Yes, I think it makes sense (for your particular case, since the change is relatively minor), though obviously that sort of thing could scale out of control fairly quickly.
IMHO, the most logical way to go about it would be to create different solution/project configurations for each version, then define a custom symbol (say, NET40) in your 4.0 configurations, then use that with an #if. I'm not certain if configurations will allow you to change the runtime version (that would obviously be the perfect solution), but your worst-case is having to change the version manually.
EDIT: I just saw the answer linked to in Joshua's answer, and that seems like a more streamlined solution, but I'll leave this here anyway, since it does, strictly speaking, answer the question.
You can prepare your code for .NET 4.0 and write the similar code for the .NET 3.5 base on framework detection.
#if NOT_RUNNING_ON_4
public static class GuidExtensions
{
public static bool TryParse(this string s, out Guid result)
{
if (s.IsNullOrEmpty())
return null;
try
{
return new Guid(s);
}
catch (FormatException)
{
return null;
}
}
}
#else
#error switch parsing to .NET 4.0
#endif
And put his line to your *.csproj
<DefineConstants Condition=" '$(TargetFrameworkVersion)' != 'v4.0' ">NOT_RUNNING_ON_4</DefineConstants>
I have been developing a managed extensibility framework application for the last several months using the community preview. I have been using the GetExportedValues() method and the PartCreationPolicy(CreationPolicy.NonShared) to fake a class factory (since only the silverlight version supports a factory). This was working great until I upgraded the project to use .net 4.0. There is no error, it just doesn't work.
So why did this code stop working? The code follows:
The factory method:
public static IEnumerable<DataActionBase> GetActionsFromDirectory(string PluginsFolder)
{
IEnumerable<DataActionBase> result = null;
var catalog = new DirectoryCatalog(PluginsFolder);
var container = new CompositionContainer(catalog: catalog);
result = container.GetExportedValues<DataActionBase>();
return result;
}
Example Export Class:
[Export(typeof(DataActionBase))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class AnAction : DataActionBase
{
....
}
Have you recompiled your extensions against .NET 4.0? If the extensions reference the codeplex preview version of MEF, then the .NET 4.0 MEF won't pick them up. This is because the export attribute would be coming from an assembly with a different strong name, which .NET 4.0 MEF knows nothing about.