Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When the path contains Chinese characters, the application fails to run. #232

Open
git20210101 opened this issue Nov 13, 2024 · 26 comments
Open

Comments

@git20210101
Copy link

When the path contains Chinese characters, the application fails to run.

@agracio
Copy link
Owner

agracio commented Nov 13, 2024

Could you give me some examples.

@git20210101
Copy link
Author

git20210101 commented Nov 14, 2024

thanks for your reply.
My English is not good, so I used a translation tool for the following content.

My Code:

static void Main(string[] args)
{
    var data = new { a = 1, b = 2 };
    Console.WriteLine(JsSum(data).Result);
    Console.ReadLine();
}

static async Task<int> JsSum(dynamic data)
{
    string jsCode = $"function sum(a,b){{\r\n    return a+b;\r\n}}\r\nreturn function (data, callback) {{\r\n    var result = sum(data.a, data.b);\r\n    callback(null, result);\r\n  }}";
    Func<object, Task<object>> ExecJs = Edge.Func(jsCode);
    int result = Convert.ToInt32(await ExecJs(data));
    return result;
}

If the path does not contain any English characters, it can output correctly. Otherwise, the application will exit directly. When I run it using CMD, it outputs the following content.

image

This issue appears to be caused by Chinese character encoding problems. I have debugged the code in your EdgeJs.cs and found no issues. The problem seems to occur when calling libnode.dll during NodeStar execution, leading to encoding issues.
If you cannot output Chinese characters, you can rename the folder to '测试'. This will allow you to see the effect.

@agracio
Copy link
Owner

agracio commented Nov 14, 2024

I thought this issue was already fixed by one of old PRs, let me take a closer look.
And do not worry about your english I am sure we can communicate, translation tool is doing a perfect job.

@agracio
Copy link
Owner

agracio commented Nov 14, 2024

I am getting a different exception, what version of nuget are you using? Old one is called Edge.js and mine is published as EdgeJs.
For reference I copied compiled code to a new directory with chinese characters that you provided and running it by clicking ConsoleApp.exe.

Unhandled Exception: System.DllNotFoundException: Unable to load DLL 'libnode.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
   at EdgeJs.Edge.NodeStartx64(Int32 argc, String[] argv)
   at EdgeJs.Edge.<>c__DisplayClass18_0.<Func>b__0()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

@agracio
Copy link
Owner

agracio commented Nov 14, 2024

Found PR that was supposed to fix the problem: tjanczuk/edge#555. Maybe it did not fix all the issues and some characters are still not supported.

@agracio
Copy link
Owner

agracio commented Nov 14, 2024

Depending on what kind of non-english characters I use in path it blows up with different exceptions. Not sure it can be fixed very easily.

@git20210101
Copy link
Author

The project framework is .NET Framework 4.8, and the Edge.js version is 9.3.0.0. I have also tried integrating the latest code directly into the project, but the same issue persists.

I believe that solving this problem might require recompiling libnode.dll. Here is the relevant code:
argv.Add(shortPath.ToString()); argv.Add(string.Format("-EdgeJs:{0}", Path.Combine(edgeDirectory, "EdgeJs.dll"))); nodeStart(argv.Count, argv.ToArray());

The argv parameters print correctly, so the issue must be with the nodeStart function.

@agracio
Copy link
Owner

agracio commented Nov 14, 2024

I am using EdgeJs 20.12.3 - this is the nuget package from edge-js, Edge.js nuget package is from old edge. Encountering the problem above.
Relevant path is:

    if (IntPtr.Size == 4)
    {
        LoadLibrary(AssemblyDirectory + @"\edge\x86\libnode.dll");
        nodeStart = NodeStartx86;
    }
    else if (IntPtr.Size == 8)
    {
        LoadLibrary(AssemblyDirectory + @"\edge\x64\libnode.dll");
        nodeStart = NodeStartx64;
    }

Possible fix for that particular issue changing

[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
static extern int LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);`

to

[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
static extern int LoadLibrary( [MarshalAs(UnmanagedType.LPUTF8Str)] string lpLibFileName);`

@agracio
Copy link
Owner

agracio commented Nov 14, 2024

This is the file you should be looking at: https://github.com/agracio/edge-js/blob/master/src/double/Edge.js/dotnet/EdgeJs.cs

@agracio
Copy link
Owner

agracio commented Nov 14, 2024

Let me know if you encounter the same problem as I did when using EdgeJs 20.12.3

@git20210101
Copy link
Author

I am not using the wrong files, but the UnmanagedType enumeration in the .NET Framework does not have the LPUTF8Str option. Since using version 20.12.3 from NuGet did not work, I downloaded the code from GitHub to use it. Therefore, my responses regarding the version issues were a bit confusing.
image

@agracio
Copy link
Owner

agracio commented Nov 14, 2024

Could you tell me what exception you getting when using 20.12.3. Looks like you right about UnmanagedType.LPUTF8Str it is only available in .NET Core

@git20210101
Copy link
Author

git20210101 commented Nov 14, 2024

thanks for your reply. My English is not good, so I used a translation tool for the following content.

My Code:

static void Main(string[] args)
{
    var data = new { a = 1, b = 2 };
    Console.WriteLine(JsSum(data).Result);
    Console.ReadLine();
}

static async Task<int> JsSum(dynamic data)
{
    string jsCode = $"function sum(a,b){{\r\n    return a+b;\r\n}}\r\nreturn function (data, callback) {{\r\n    var result = sum(data.a, data.b);\r\n    callback(null, result);\r\n  }}";
    Func<object, Task<object>> ExecJs = Edge.Func(jsCode);
    int result = Convert.ToInt32(await ExecJs(data));
    return result;
}

If the path does not contain any English characters, it can output correctly. Otherwise, the application will exit directly. When I run it using CMD, it outputs the following content.

image

This issue appears to be caused by Chinese character encoding problems. I have debugged the code in your EdgeJs.cs and found no issues. The problem seems to occur when calling libnode.dll during NodeStar execution, leading to encoding issues. If you cannot output Chinese characters, you can rename the folder to '测试'. This will allow you to see the effect.

I encountered this issue when using version 20.12.3.
Did you encounter this issue when using version 20.12.3 and changing the folder name to Chinese?
Please try it under the .NET Framework.

@agracio
Copy link
Owner

agracio commented Nov 14, 2024

I encountered this issue when using chinese characters that you provided: #232 (comment)
Your image is not loading.
I am using .NET Framework 4.8

@git20210101
Copy link
Author

git20210101 commented Nov 14, 2024

I don't know if you can't see the images, so I'll copy the error message for you.

Microsoft Windows [版本 10.0.22631.4460]
(c) Microsoft Corporation。保留所有权利。

C:\Users\Zero\Desktop\测试\Debug>ConsoleApp1.exe
node:internal/modules/cjs/loader:1146
  throw err;
  ^

Error: Cannot find module 'C:\Users\Zero\Desktop\����\Debug\edge\DOUBLE~1.'
    at Module._resolveFilename (node:internal/modules/cjs/loader:1143:15)
    at Module._load (node:internal/modules/cjs/loader:984:27)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:135:12)
    at node:internal/main/run_main_module:28:49 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}

Node.js v20.12.2

C:\Users\Zero\Desktop\测试\Debug> 

You can see that the word "测试" is garbled

@agracio
Copy link
Owner

agracio commented Nov 14, 2024

This should happen on earlier versions before tjanczuk/edge#555 was merged, very strange.
But either way it does not work, any chance you can avoid using chinese characters in your development and deployment?

@git20210101
Copy link
Author

Since this is a client-side application, I cannot guarantee where the users will place the program. In China, folders are commonly named using Chinese characters.

@agracio
Copy link
Owner

agracio commented Nov 14, 2024

This is a complicated issue to resolve, so not sure when or if I am able to figure it out.
Possibly tjanczuk/edge#555 needs to be applied to more paths but it wont be easy.
But most importantly your issue should not be happening on 20.12.3 so this means that the solution does not work at all for you while it does work for me.

@agracio
Copy link
Owner

agracio commented Nov 14, 2024

Could you start a fresh project using 20.12.3 and confirm that you getting Error: Cannot find module 'C:\Users\Zero\Desktop\����\Debug\edge\DOUBLE~1.' to make sure it is not caused by some lingering artefacts.

This is especially strange as I am not able to go past LoadLibrary(AssemblyDirectory + @"\edge\x64\libnode.dll"); in my project using chinese characters but you are getting past it.

@git20210101
Copy link
Author

git20210101 commented Nov 14, 2024

I'm not entirely clear about the logic in the code, but is it possible to use a method similar to SetAssemblyDirectory to set edgeDirectory to point to a different path? This way, I could achieve the desired functionality by copying files. I have tried directly assigning a value to edgeDirectory in SetAssemblyDirectory, but the program does not run correctly.

The error I sent you was generated from a new project that only uses Edge.js. After building the project successfully, placing the debug/release folder in a Chinese-named directory causes this issue. It took me a long time to figure out that this was the cause of the error.

I can bypass the LoadLibrary method, as the issue might be related to the PC environment.

@agracio
Copy link
Owner

agracio commented Nov 14, 2024

Why do you think that the issue is edgeDirectory ?
It looks like you having an issue loading edge/double_edge.js which is using AssemblyDirectory plus a patch from tjanczuk/edge#555.
Maybe the patch is that actually causes the problems, since you locale is set to Chinese maybe the patch should be ignored and instead argv.Add(AssemblyDirectory + "\\edge\\double_edge.js"); should be used.
I am not sure myself tbh since we are getting different errors on our systems, the only difference I can think of is your system locale vs my locale.

Try recompiling Edge.dll without the patch and just using argv.Add(AssemblyDirectory + "\\edge\\double_edge.js");, I am curious what will happen then.

@git20210101
Copy link
Author

git20210101 commented Nov 14, 2024

I tried this method yesterday. Even after removing the patch and using the original values, the same issue persists.

I believe the issue might be with how libnode.dll handles Chinese characters

@agracio
Copy link
Owner

agracio commented Nov 14, 2024

It is almost impossible for me to troubleshoot since we are getting different errors on our systems.

I believe the issue might be with how libnode.dll handles Chinese characters

But then the error would be different. libnode.dll is not compiled using any of edge-js variables, it is compiled straight from Node.js source.

You can compile your own libnode.dll by downloading Node.js source from https://nodejs.org/en/download/source-code and then running vcbuild.bat release x64 dll from its root, but that would get you the same libnode.dll that EdgeJs nuget uses.

@git20210101
Copy link
Author

git20210101 commented Nov 14, 2024

Why do you think that the issue is edgeDirectory ? It looks like you having an issue loading edge/double_edge.js which is using AssemblyDirectory plus a patch from tjanczuk/edge#555. Maybe the patch is that actually causes the problems, since you locale is set to Chinese maybe the patch should be ignored and instead argv.Add(AssemblyDirectory + "\\edge\\double_edge.js"); should be used. I am not sure myself tbh since we are getting different errors on our systems, the only difference I can think of is your system locale vs my locale.

Try recompiling Edge.dll without the patch and just using argv.Add(AssemblyDirectory + "\\edge\\double_edge.js");, I am curious what will happen then.

edgeDirectory is not the issue. I just want to try another approach to solve this problem. Specifically, I plan to copy all Edge.js-related files to a temporary directory, which will not contain any Chinese characters. Then, I can load and use these files from the temporary directory.

Both assemblyDirectory and edgeDirectory will cause the program to crash if they contain any Chinese characters.

@git20210101
Copy link
Author

git20210101 commented Nov 14, 2024

The issue has been resolved. Using relative paths when passing parameters works fine.

 argv.Add(@"edge\double_edge.js");
 argv.Add("-EdgeJs:EdgeJs.dll");

 nodeStart(argv.Count, argv.ToArray());

@agracio
Copy link
Owner

agracio commented Nov 14, 2024

I am happy it is resolved for you however I am not sure introducing this into the main repo would not cause problems for other people.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants