microsoft / node-api-dotnet

Advanced interoperability between .NET and JavaScript in the same process.
MIT License
495 stars 53 forks source link

Invariant Culture #309

Closed diegoaraujolima closed 3 months ago

diegoaraujolima commented 3 months ago

I noticed that when using the library using:

const dotnet = require('node-api-dotnet');

I noticed that it doesn't load the Culture that the operating system uses (in my case Windows).

As a result, it does not allow you to use a specific Cuture. When trying to create a culture using:

dotnet.System.Globalization.CultureInfo.CurrentCulture = new dotnet.System.Globalization.CultureInfo("pt-BR")

It returns the error:

Globalization Invariant Mode is not supported

Researching some articles, I saw that it is possible to disable this using the line in the csproj file:

<InvariantGlobalization>false</InvariantGlobalization>

However, the error occurs before I load an Assembly just using dotnet.System.Globalization.

Is it possible in any way how I want to use Culture?

jasongin commented 3 months ago

I can't reproduce this. I tested the following code:

const dotnet = require('node-api-dotnet');
const Console = dotnet.System.Console;
const CultureInfo = dotnet.System.Globalization.CultureInfo;

Console.WriteLine("Current culture: " + CultureInfo.CurrentCulture);
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo('pt-BR');
Console.WriteLine("Current culture: " + CultureInfo.CurrentCulture);

It produced output:

Current culture: en-US
Current culture: pt-BR

If I add "System.Globalization.Invariant": true to node_modules\node-api-dotnet\net8.0\Microsoft.JavaScript.NodeApi.runtimeconfig.json (as described in this doc), then the same code above throws an exception:

Error: Only the invariant culture is supported in globalization-invariant mode. See https://aka.ms/GlobalizationInvariantMode for more information. (Parameter 'name')
pt-br is an invalid culture identifier.
    at System.Globalization.CultureInfo.GetCultureInfo(String name)

But that is different from your error. So I don't understand what the issue is.

diegoaraujolima commented 3 months ago

I looked for this file in the path you provided and it looks like this:

{
  "runtimeOptions": {
    "tfm": "net8.0",
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "8.0.0"
    },
    "configProperties": {
      "System.Globalization.Invariant": true,
      "System.Globalization.PredefinedCulturesOnly": true,
      "System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
      "System.Resources.UseSystemResourceKeys": true,
      "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false,
      "System.Runtime.InteropServices.EnableConsumingManagedCodeFromNativeHosting": true
    }
  }
}

I didn't change this configuration because I installed the package via npm, which makes me suspect that npm already comes with this configuration this way.

To be sure, I just created a new project:

npm init
npm install node-api-dotnet

And when checking the file in the path:

node_modules\node-api-dotnet\net8.0\Microsoft.JavaScript.NodeApi.runtimeconfig.json

it has exactly this configuration above.

jasongin commented 3 months ago

You're right, I had tested with a private build that had different runtimeconfig file.

The runtimeconfig in the npm package is not correct. I looks like it is getting mixed up with the intended config for the native host. The "native host" is the platform-specific .node binary that bootstraps the .NET runtime. It is compiled with .NET Native AOT, and since it doesn't require globalization I had disabled it to make the binary smaller.

I'll get that config sorted out and publish a fixed npm package. Meanwhile you can work around the issue by manually editing that runtimeconfig file.

diegoaraujolima commented 3 months ago

Yes, I will solve it by editing the file. Thank you for your attention.