Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

.NET Standard and Microsoft.Win32.Registry conflict Editor / Runtime

Discussion in 'Experimental Scripting Previews' started by bdovaz, Oct 10, 2018.

  1. bdovaz

    bdovaz

    Joined:
    Dec 10, 2011
    Posts:
    1,052
    Hi @joncham @JoshPeterson ,

    I'm trying to use in a project Win 32 registry API in both editor and runtime scripts.

    First scenario (a new project configured with .NET Standard 2.0):

    1. If I create a editor script using that API it works because it gets resolved from "mscorlib" ({UNITY_PATH}/Data\MonoBleedingEdge\lib\mono\4.7.1-api\mscorlib.dll).
    2. If I create a runtime script using that API it complains about the API that doesn't exist. That's expected, that API doesn't come "by default".

    Second scenario (adding Microsoft.Win32.Registry assemblies and dependencies):

    1. If I create a editor script using that API it complains about having it in two assemblies "mscorlib" and "Microsoft.Win32.Registry".
    2. If I create a runtime script using that API it works because it gets resolved from the added assembly.

    As you can imagine I don't know what to do because I can't have a solution that works for both scenarios (editor / runtime scripts on Unity editor).

    I suppose that it's a scenario that it's not tested by Unity.
     
  2. mike-voorhees

    mike-voorhees

    Unity Technologies

    Joined:
    Aug 9, 2016
    Posts:
    46
    The recommend solution when trying to use an API that is part of the .NET Framework, but is not part of .NET Standard 2.0 is to change the Api Compatability Level in the Player Setters to .NET 4.x rather than adding assemblies such as Microsoft.Win32.Registry.

    Can you give that a try and see if it works for you?
     
    asRyoyu likes this.
  3. bdovaz

    bdovaz

    Joined:
    Dec 10, 2011
    Posts:
    1,052
    I suppose that it should work but I do not want to do this...

    If my project was only for Windows it would be ok but it's cross platform so I don't want to change from .NET Standard to .NET 4x in order to use an API...

    In a regular .NET Core project you can target all the platforms that are supported and use Microsoft.Win32.Registry nuget package on the platforms that it's implemented (Windows) but it compiles.
     
  4. mike-voorhees

    mike-voorhees

    Unity Technologies

    Joined:
    Aug 9, 2016
    Posts:
    46
    The API's available in the .NET 4.x Api Compatibility Level are the same regardless of platform. API's such as Microsoft.Win32.Registry that are not supported on say, OSX, will throw at runtime if you call an API that is not supported. At compile time, the API will be there and everything will compile fine.
     
  5. bdovaz

    bdovaz

    Joined:
    Dec 10, 2011
    Posts:
    1,052
    I mean that Unity recommends by default.NET Standard and not .NET 4.x. I suppose that it's a different code path and behave different.

    That's why I said that changing it can have other side effects.
     
  6. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    The main difference between .NET Standard 2.0 and .NET 4.x is the API surface. There are a few different code paths for unsupported APIs on given platforms, but I don't think you will see too much behavior difference between the two.

    The reason we suggest the .NET Standard 2.0 profile is for code size - it is a smaller API surface, so the output executable is smaller. However, we have the .NET 4.x API for exactly this purpose - API methods that don't exist in .NET Standard 2.0 can be used with .NET 4.x.
     
  7. bdovaz

    bdovaz

    Joined:
    Dec 10, 2011
    Posts:
    1,052
    I understand but you also need to understand that if we import nuget packages that target .NET Standard and depend on assemblies like this will cause problems...

    You should support this scenario because changing profile from .NET Standard to .NET 4.x is a "workaround".

    You need to expect more developers using nuget packages more frequently from now on and there are multiple scenarios like this.
     
    fincha likes this.
  8. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    Sorry, maybe I am misunderstanding the situation. Does the nuget package that targets .NET Standard 2.0 use the Microsoft.Win32.Registry API?
     
  9. unitylepi

    unitylepi

    Joined:
    May 21, 2018
    Posts:
    34
    With .NET 4.x Equivalent set, I still get: "error CS1069: The type name 'Registry' could not be found in the namespace 'Microsoft.Win32'. This type has been forwarded to assembly 'Microsoft.Win32.Registry"

    It's kind of odd that it's still sending it to Microsoft.Win32.Registry even tho it just told me that namespace cannot be found?
     
  10. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    I'm not sure why this happens. Can you send us a bug report with your project?
     
  11. julienkay

    julienkay

    Joined:
    Nov 12, 2013
    Posts:
    171
    I'm hitting the same issue. Do you still need a bug report for this?
     
  12. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,936
    Yes, we don't have a bug report for this issue. If you can reproduce it in a project you can submit, please do so. Thanks!
     
  13. julienkay

    julienkay

    Joined:
    Nov 12, 2013
    Posts:
    171
    I'll take my comment back, sorry for the confusion. I just checked again and can confirm that using the Registry class in the namespace Microsoft.Win32 works as intended, if I set the API Compatibility Level to 4.x.

    There might be an issue where an error is thrown by Unity wrongfully, which is why I thought it didn't work at first. But even if that's the case, I can't reproduce it right now.
     
  14. amirmahdinassiri

    amirmahdinassiri

    Joined:
    May 22, 2020
    Posts:
    2
    My problem is almost the same:

    I have an SDK library which is multi-targeting .Net standard 2.0 and .Net framework 4.6.1. The SDK library uses Microsoft.Win32.Registry when the runtime is .Net standard 2.0 and it's not being used when the runtime is .Net framework 4.6.1. My project is set to use API compatibility level .Net 4.x, but I will get the following error no matter that the Microsoft.Win32.Registry is not being used:

    Library\PackageCache\com.unity.ide.rider@1.1.4\Rider\Editor\Discovery.cs(248,24): error CS0433: The type 'Registry' exists in both 'Microsoft.Win32.Registry, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' and 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

    And honestly, I can't find where is the other reference to Microsoft.Win32.Registry! I'm having the only reference and the only DLL with a version of 4.7! I know that mscorlib.dll has this library included, is that the problem? The thing is, the error message doesn't even reflect my file's version (4.7)!

    The error doesn't allow Unity to run my game scene, as it is a compile error. But as a workaround, if I remove the folder "Library\PackageCache\com.unity.ide.rider@1.1.4" in my Unity project directory, the error disappears!

    Additionally, I get another error while importing my SDK, which is not related to the previous problem. I'll get the following error:

    Multiple plugins with the same name 'e_sqlite3'. That means one or more plugins are set to be compatible with Editor. Only one plugin at the time can be used by Editor.

    There are multiple "e_sqlite3" DLLs specific to different runtimes (win-arm, win-x64, win-x86), and the appropriate one is being loaded by the reflection code used in Microsoft.EntityFrameworkCore.Sqlite. Why should I get an error for such a scenario which is well supported by the runtime?

    Thanks for any help in advance.
     
    Oscar_Munoz likes this.
  15. RGV

    RGV

    Joined:
    Jan 25, 2016
    Posts:
    48
    We're facing this RegistryKey problem only when we isolate code within an assembly definition. I mean, code which can perfectly import and use RegistryKey when it's out of any asmdef scope — it is, in Assembly-CSharp default one —, loses its access to RegistryKey after being included in any asmdef scope.

    I really don't figure out how to reference mscorlib.dll from an assembly definition having Api Compatibility Level set to .NET Standard 2.0...
     
    Last edited: Apr 29, 2021
  16. Fuzzypup

    Fuzzypup

    Joined:
    Aug 13, 2013
    Posts:
    190
    Two of my games run on Unity 2019 and this works correctly.
    Currently I am running Unity Personal 2020.3.4f1 for my 3rd game and I have this same issue.

    Project Settings -> Player -> Api Compatibility Level - to .NET 4.x -> Close -> Save Project

    Restart Unity and it worked.
     
    asRyoyu likes this.
  17. Fuzzypup

    Fuzzypup

    Joined:
    Aug 13, 2013
    Posts:
    190
    Wait I noticed it says it isn't working in VS but it is working when I run it in the player.
     
  18. RGV

    RGV

    Joined:
    Jan 25, 2016
    Posts:
    48
    Yup, I pointed .NET Standard 2.0 is where the problem lies. We also set to .NET 4.x but still trying to figure out how to manage this when you can't upgrade to 4.x — for whatever reason.

    So we had this problem on Unity 2019.3, indeed!
     
  19. Fuzzypup

    Fuzzypup

    Joined:
    Aug 13, 2013
    Posts:
    190
    My API was set to 2.0 and I set it to 4.x and it worked.
     
    Rugbug_Redfern likes this.
  20. mukiulizzy

    mukiulizzy

    Joined:
    Sep 18, 2020
    Posts:
    1
    If there are no errors in the editor after changing to 4.0, but the error persists in Visual Studio, delete the script and re-create it.