From 6df2fb7b7d14bb8c368be286e9fa50cbfbeee2e0 Mon Sep 17 00:00:00 2001 From: agracio Date: Fri, 3 May 2024 20:16:26 +0100 Subject: [PATCH] improving assembly loader for .NET Core, minor cleanup --- .jshintrc | 56 --------- .npmignore | 5 +- README.md | 4 +- package.json | 2 +- samples/203_x509store.js | 81 ++++++++---- .../Edge.js/dotnetcore/coreclrembedding.cs | 119 ++++++++++++------ test/104_csx.js | 8 +- tools/build_double.bat | 46 +++---- 8 files changed, 171 insertions(+), 150 deletions(-) delete mode 100644 .jshintrc diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 7ca0315b..00000000 --- a/.jshintrc +++ /dev/null @@ -1,56 +0,0 @@ -{ - "globals": { - "_": true, - "after": true, - "async": true, - "afterEach": true, - "afterEach": true, - "Backbone": true, - "before": true, - "beforeEach": true, - "describe": true, - "expect": true, - "iit": true, - "it": true, - "jasmine": true, - "moment": true, - "runs": true, - "sinon": true, - "spyOn": true, - "waits": true, - "waitsFor": true, - "xit": true, - "xdescribe": true - }, - - "options": { - "asi" : false, - "bitwise" : true, - "boss" : false, - "browser" : true, - "curly" : true, - "debug": false, - "devel": false, - "eqeqeq": true, - "evil": false, - "expr": true, - "forin": false, - "immed": true, - "jquery" : true, - "latedef" : false, - "laxbreak": false, - "multistr": true, - "newcap": true, - "noarg": true, - "node" : true, - "noempty": false, - "nonew": true, - "onevar": false, - "plusplus": false, - "regexp": false, - "strict": false, - "sub": false, - "trailing" : true, - "undef": true - } -} \ No newline at end of file diff --git a/.npmignore b/.npmignore index ac656477..cd577e1c 100644 --- a/.npmignore +++ b/.npmignore @@ -92,8 +92,11 @@ tools/*.cs tools/*.vbs tools/nuget *.nupkg -appveyor.* +appveyor*.* .github tools/coverage.js tools/test*.js tools/download*.js +test/mochawesome-report +mochawesome-report +mochawesome.json diff --git a/README.md b/README.md index ba14e614..e6873b9d 100644 --- a/README.md +++ b/README.md @@ -705,7 +705,9 @@ In that case the default typeName of `My.Edge.Samples.Startup` and methodName of ### How to: specify additional CLR assembly references in C# code -When you provide C# source code and let edge compile it for you at runtime, edge will by default reference only mscorlib.dll and System.dll assemblies. If you're using .NET Core, we automatically reference the most recent versions of the System.Runtime, System.Threading.Tasks, System.Dynamic.Runtime, and the compiler language packages, like Microsoft.CSharp. In applications that require additional assemblies you can specify them in C# code using a special hash pattern, similar to Roslyn. For example, to use ADO.NET you must reference System.Data.dll: +When you provide C# source code and let edge compile it for you at runtime, edge will by default reference only mscorlib.dll and System.dll assemblies. If you're using .NET Core, we automatically reference the most recent versions of the System. Runtime, System.Threading.Tasks, and the compiler language packages, like Microsoft.CSharp. In applications that require additional assemblies you can specify them in C# code using a special hash pattern, similar to Roslyn. For example, to use ADO.NET you must reference System.Data.dll: + +#### NOTE: `#r` and `references: [ 'MyDll.dll' ]` references only work when using .NET Framework 4.5 ```javascript var add7 = edge.func(function() {/* diff --git a/package.json b/package.json index 1aa55f0c..16169c2a 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "url": "http://tomasz.janczuk.org", "twitter": "tjanczuk" }, - "version": "21.7.4", + "version": "21.7.5", "description": "Edge.js: run .NET and Node.js in-process on Windows, Mac OS, and Linux", "tags": [ "owin", diff --git a/samples/203_x509store.js b/samples/203_x509store.js index 74a6d9bb..c2969db5 100644 --- a/samples/203_x509store.js +++ b/samples/203_x509store.js @@ -2,34 +2,67 @@ var edge = require('../lib/edge'); -var listCertificates = edge.func(function() {/* - #r "System.dll" - - using System.Collections.Generic; - using System.Security.Cryptography.X509Certificates; - - async (dynamic data) => - { - X509Store store = new X509Store( - (string)data.storeName, - (StoreLocation)Enum.Parse(typeof(StoreLocation), (string)data.storeLocation)); - store.Open(OpenFlags.ReadOnly); - try +// var listCertificates = edge.func(function() {/* +// //#r "System.Security.Cryptography" + +// using System.Security.Cryptography; +// using System.Collections.Generic; +// using System.Security.Cryptography.X509Certificates; + +// async (dynamic data) => +// { +// X509Store store = new X509Store( +// (string)data.storeName, +// (StoreLocation)Enum.Parse(typeof(StoreLocation), (string)data.storeLocation)); +// store.Open(OpenFlags.ReadOnly); +// try +// { +// List result = new List(); +// foreach (X509Certificate2 certificate in store.Certificates) +// { +// result.Add(certificate.Subject); +// } + +// return result; +// } +// finally +// { +// store.Close(); +// } +// } +// */}); + +var listCertificates = edge.func({ + source: function() {/* + + using System.Security.Cryptography; + using System.Collections.Generic; + using System.Security.Cryptography.X509Certificates; + + async (dynamic data) => { - List result = new List(); - foreach (X509Certificate2 certificate in store.Certificates) + X509Store store = new X509Store( + (string)data.storeName, + (StoreLocation)Enum.Parse(typeof(StoreLocation), (string)data.storeLocation)); + store.Open(OpenFlags.ReadOnly); + try { - result.Add(certificate.Subject); - } + List result = new List(); + foreach (X509Certificate2 certificate in store.Certificates) + { + result.Add(certificate.Subject); + } - return result; - } - finally - { - store.Close(); + return result; + } + finally + { + store.Close(); + } } - } -*/}); + */}, + references: [ 'System.Security.Cryptography' ] +}); var result = listCertificates({ storeName: 'My', storeLocation: 'LocalMachine' }, true); console.log(result); diff --git a/src/double/Edge.js/dotnetcore/coreclrembedding.cs b/src/double/Edge.js/dotnetcore/coreclrembedding.cs index 60476f83..1ded9085 100644 --- a/src/double/Edge.js/dotnetcore/coreclrembedding.cs +++ b/src/double/Edge.js/dotnetcore/coreclrembedding.cs @@ -237,7 +237,7 @@ public void LoadDependencyManifest(string dependencyManifestFile) DebugMessage("EdgeAssemblyResolver::LoadDependencyManifest (CLR) - Finished"); } - + private void AddDependencies(DependencyContext dependencyContext, bool standalone) { DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Adding dependencies for {0}", dependencyContext.Target.Framework); @@ -245,10 +245,22 @@ private void AddDependencies(DependencyContext dependencyContext, bool standalon AddCompileDependencies(dependencyContext, standalone); Dictionary supplementaryRuntimeLibraries = new Dictionary(); + var runtimePath = Path.GetDirectoryName(RuntimeEnvironment.RuntimePath); foreach (RuntimeLibrary runtimeLibrary in dependencyContext.RuntimeLibraries) { - + if (!_libraries.ContainsKey(runtimeLibrary.Name) && CompileAssemblies.ContainsKey(runtimeLibrary.Name)) + { + _libraries[runtimeLibrary.Name] = CompileAssemblies[runtimeLibrary.Name]; + } + + if (_libraries.ContainsKey(runtimeLibrary.Name) && CompileAssemblies.ContainsKey(runtimeLibrary.Name)) + { + AddNativeAssemblies(dependencyContext, runtimeLibrary); + AddSupplementaryRuntime(runtimeLibrary); + continue; + } + DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Processing runtime dependency {1} {0}", runtimeLibrary.Name, runtimeLibrary.Type); List assets = runtimeLibrary.RuntimeAssemblyGroups.GetRuntimeAssets(RuntimeInformation.RuntimeIdentifier).ToList(); @@ -264,7 +276,7 @@ private void AddDependencies(DependencyContext dependencyContext, bool standalon string assemblyPath; if(runtimeLibrary.Type == "project") - assemblyPath = Path.Combine(RuntimeEnvironment.ApplicationDirectory, assetPath); + assemblyPath = Path.Combine(RuntimeEnvironment.ApplicationDirectory, assetPath); else if (standalone) assemblyPath = Path.Combine(RuntimeEnvironment.ApplicationDirectory, Path.GetFileName(assetPath)); else @@ -277,7 +289,7 @@ private void AddDependencies(DependencyContext dependencyContext, bool standalon if (!File.Exists(assemblyPath)) { - assemblyPath = Path.Combine(RuntimeEnvironment.RuntimePath, Path.GetFileName(assemblyPath)); + assemblyPath = Path.Combine(runtimePath, Path.GetFileName(assemblyPath)); } if (!_libraries.ContainsKey(runtimeLibrary.Name)) @@ -285,7 +297,7 @@ private void AddDependencies(DependencyContext dependencyContext, bool standalon if (File.Exists(assemblyPath)) { _libraries[runtimeLibrary.Name] = assemblyPath; - DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Added runtime assembly {0}", assemblyPath); + DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Added runtime assembly {1} from {0}", assemblyPath, runtimeLibrary.Name); } else { @@ -304,14 +316,13 @@ private void AddDependencies(DependencyContext dependencyContext, bool standalon if (File.Exists(assemblyPath)) { supplementaryRuntimeLibraries[libraryNameFromPath] = assemblyPath; - DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Added supplementary runtime assembly {0}", assemblyPath); + DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Added supplementary runtime assembly {1} from {0}", assemblyPath, libraryNameFromPath); } else { DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Could not resolve supplementary runtime assembly {0}", assemblyPath); } - } if (!CompileAssemblies.ContainsKey(runtimeLibrary.Name)) @@ -319,13 +330,11 @@ private void AddDependencies(DependencyContext dependencyContext, bool standalon if (File.Exists(assemblyPath)) { CompileAssemblies[runtimeLibrary.Name] = assemblyPath; - DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Added compile assembly {0}", - assemblyPath); + DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Added compile assembly {1} from {0}", assemblyPath, runtimeLibrary.Name); } else { - DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Could not resolve compile assembly {0}", - assemblyPath); + DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Could not resolve compile assembly {0}", assemblyPath); } } @@ -336,7 +345,8 @@ private void AddDependencies(DependencyContext dependencyContext, bool standalon } else { - AddRuntimeDependency(runtimeLibrary); + DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - RuntimeAssemblyGroups does not have RuntimeAssets or DefaultAssets"); + if (!CompileAssemblies.ContainsKey(runtimeLibrary.Name)) AddCompileDependencyFromRuntime(runtimeLibrary); } foreach (string libraryName in supplementaryRuntimeLibraries.Keys) @@ -354,37 +364,57 @@ private void AddDependencies(DependencyContext dependencyContext, bool standalon CompileAssemblies[libraryName] = supplementaryRuntimeLibraries[libraryName]; } } - - List nativeAssemblies = runtimeLibrary.GetRuntimeNativeAssets(dependencyContext, RuntimeInformation.RuntimeIdentifier).ToList(); - if (nativeAssemblies.Any()) - { - DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Adding native dependencies for {0}", RuntimeInformation.RuntimeIdentifier); + AddNativeAssemblies(dependencyContext, runtimeLibrary); + } + } + + private void AddSupplementaryRuntime(RuntimeLibrary runtimeLibrary) + { + var libraryNameFromPath = Path.GetFileNameWithoutExtension(_libraries[runtimeLibrary.Name]); + if (runtimeLibrary.Name != libraryNameFromPath) + { + _libraries.TryAdd(libraryNameFromPath, _libraries[runtimeLibrary.Name]); + CompileAssemblies.TryAdd(libraryNameFromPath, _libraries[runtimeLibrary.Name]); + } + } + + private void AddNativeAssemblies(DependencyContext dependencyContext, RuntimeLibrary runtimeLibrary) + { + var runtimePath = Path.GetDirectoryName(RuntimeEnvironment.RuntimePath); + List nativeAssemblies = runtimeLibrary.GetRuntimeNativeAssets(dependencyContext, RuntimeInformation.RuntimeIdentifier).ToList(); + + if (nativeAssemblies.Any()) + { + DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Adding native dependencies for {0}", RuntimeInformation.RuntimeIdentifier); - foreach (string nativeAssembly in nativeAssemblies) + foreach (var nativeAssembly in nativeAssemblies) + { + var nativeAssemblyPath = Path.Combine(_packagesPath, runtimeLibrary.Name, runtimeLibrary.Version, nativeAssembly.Replace('/', Path.DirectorySeparatorChar)); + if (!File.Exists(nativeAssemblyPath)) { - string nativeAssemblyPath = Path.Combine(_packagesPath, runtimeLibrary.Name, runtimeLibrary.Version, nativeAssembly.Replace('/', Path.DirectorySeparatorChar)); + nativeAssemblyPath = Path.Combine(runtimePath, nativeAssembly.Replace('/', Path.DirectorySeparatorChar)); + } - if (File.Exists(nativeAssemblyPath)) - { - _nativeLibraries[Path.GetFileNameWithoutExtension(nativeAssembly)] = nativeAssemblyPath; - DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Adding native assembly {0} at {1}", + if (File.Exists(nativeAssemblyPath)) + { + _nativeLibraries[Path.GetFileNameWithoutExtension(nativeAssembly)] = nativeAssemblyPath; + DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Adding native assembly {0} at {1}", Path.GetFileNameWithoutExtension(nativeAssembly), nativeAssemblyPath); - } - else - { - DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Could not resolve native assembly {0} at {1}", + } + else + { + DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Could not resolve native assembly {0} at {1}", Path.GetFileNameWithoutExtension(nativeAssembly), nativeAssemblyPath); - } - } } } } - private void AddRuntimeDependency(RuntimeLibrary runtimeLibrary) + private void AddCompileDependencyFromRuntime(RuntimeLibrary runtimeLibrary) { - DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Processing runtime dependency {0} using runtime path", runtimeLibrary.Name); + var runtimePath = Path.GetDirectoryName(RuntimeEnvironment.RuntimePath); + DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Processing compile dependency {1} {0} using runtime path {2}", runtimeLibrary.Name, runtimeLibrary.Type, runtimePath); if (!CompileAssemblies.ContainsKey(runtimeLibrary.Name)) { @@ -393,36 +423,40 @@ private void AddRuntimeDependency(RuntimeLibrary runtimeLibrary) { asset += ".dll"; } - - var runtimePath = Path.GetDirectoryName(RuntimeEnvironment.RuntimePath); + + if (asset == "runtime.native.System.dll") + { + asset = "System.dll"; + } var assemblyPath = Path.Combine(runtimePath, Path.GetFileName(asset)); if (File.Exists(assemblyPath)) { CompileAssemblies[runtimeLibrary.Name] = assemblyPath; - DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Added runtime assembly {0}", assemblyPath); + DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Added compile dependency {1} from {0}", assemblyPath, runtimeLibrary.Name); } else { - DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Could not add runtime dependency {0}", assemblyPath); + DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Could not add compile dependency {0}", assemblyPath); } } else { - DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Already present in runtime dependency list, skipping"); + DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Already present in compile dependency list, skipping"); } } private void AddCompileDependencies(DependencyContext dependencyContext, bool standalone) { + var runtimePath = Path.GetDirectoryName(RuntimeEnvironment.RuntimePath); foreach (CompilationLibrary compileLibrary in dependencyContext.CompileLibraries) { - if (compileLibrary.Assemblies == null || compileLibrary.Assemblies.Count == 0) + if (compileLibrary.Assemblies == null || compileLibrary.Assemblies.Count == 0 || CompileAssemblies.ContainsKey(compileLibrary.Name)) { continue; } - DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Processing compile dependency {0}", compileLibrary.Name); + DebugMessage("EdgeAssemblyResolver::AddDependencies (CLR) - Processing compile assembly {1} {0} {2}", compileLibrary.Name, compileLibrary.Type, compileLibrary.Assemblies[0]); string assemblyPath; @@ -434,6 +468,11 @@ private void AddCompileDependencies(DependencyContext dependencyContext, bool st if(!File.Exists(assemblyPath)) assemblyPath = Path.Combine(_packagesPath, compileLibrary.Name.ToLower(), compileLibrary.Version, compileLibrary.Assemblies[0].Replace('/', Path.DirectorySeparatorChar)); } + + if (!File.Exists(assemblyPath)) + { + assemblyPath = Path.Combine(runtimePath, Path.GetFileName(assemblyPath)); + } if (!CompileAssemblies.ContainsKey(compileLibrary.Name)) { @@ -489,7 +528,7 @@ internal void AddAssemblyPath(string assemblyPath) internal void AddCompiler(string bootstrapDependencyManifest) { - DebugMessage("EdgeAssemblyResolver::AddCompiler (CLR) - Adding the compiler from dependency manifest file {0}", bootstrapDependencyManifest); + DebugMessage("EdgeAssemblyResolver::AddCompiler (CLR) - Adding compiler from dependency manifest file {0}", bootstrapDependencyManifest); DependencyContextJsonReader dependencyContextReader = new DependencyContextJsonReader(); @@ -497,7 +536,7 @@ internal void AddCompiler(string bootstrapDependencyManifest) { DependencyContext compilerDependencyContext = dependencyContextReader.Read(bootstrapDependencyManifestStream); - DebugMessage("EdgeAssemblyResolver::AddCompiler (CLR) - Adding dependencies for the compiler"); + DebugMessage("EdgeAssemblyResolver::AddCompiler (CLR) - Adding dependencies for compiler"); AddDependencies(compilerDependencyContext, false); diff --git a/test/104_csx.js b/test/104_csx.js index 2c3148b8..02ae6a6c 100644 --- a/test/104_csx.js +++ b/test/104_csx.js @@ -199,7 +199,7 @@ describe('edge-cs', function () { var func = edge.func({ source: process.env.EDGE_USE_CORECLR ? function () {/* - //#r "System.Data.Common" + #r "System.Data.Common" using System.Threading.Tasks; using System.Data; @@ -213,7 +213,7 @@ describe('edge-cs', function () { } */} : function () {/* - //#r "System.Data.dll" + #r "System.Data.dll" using System.Threading.Tasks; using System.Data; @@ -277,7 +277,7 @@ describe('edge-cs', function () { var func = edge.func({ source: process.env.EDGE_USE_CORECLR ? function () {/* - //#r "System.Data.Common" + #r "System.Data.Common" async (input) => { @@ -285,7 +285,7 @@ describe('edge-cs', function () { } */} : function () {/* - //#r "System.Data.dll" + #r "System.Data.dll" async (input) => { diff --git a/tools/build_double.bat b/tools/build_double.bat index 0f9416b2..6d6f871d 100644 --- a/tools/build_double.bat +++ b/tools/build_double.bat @@ -29,34 +29,12 @@ if %ERRORLEVEL% neq 0 exit /b -1 call :clean_nuget_package if %ERRORLEVEL% neq 0 exit /b -1 + call :copy_nuget_package if %ERRORLEVEL% neq 0 exit /b -1 exit /b 0 -REM =========================================================== -:download_node -echo :download_node %1 - -if not exist "%SELF%\build\%1.zip" ( - node "%SELF%\download_double.js" http://github.com/nodejs/node/archive/v%1.zip "%SELF%\build\%1.zip" -) else ( - echo "%SELF%\build\%1.zip" already exists. -) - -echo :unzip %1.zip -if not exist "%SELF%\build\node-%1" ( - rem "%SELF%\build\unzip.exe" "%SELF%\build\%1.zip" "%SELF%\build" - pushd "%SELF%\build\" - powershell Expand-Archive -Path %1.zip -DestinationPath "%SELF%\build\" - rem cscript //B ..\unzip.vbs %1.zip - popd -) else ( - echo "%SELF%\build\node-%1" already exists. -) - -exit /b 0 - REM =========================================================== :build_lib echo :build_lib @@ -114,6 +92,28 @@ echo Finished building Node shared library %1 popd exit /b 0 +REM =========================================================== +:download_node +echo :download_node %1 + +if not exist "%SELF%\build\%1.zip" ( + node "%SELF%\download_double.js" http://github.com/nodejs/node/archive/v%1.zip "%SELF%\build\%1.zip" +) else ( + echo "%SELF%\build\%1.zip" already exists. +) + +echo :unzip %1.zip +if not exist "%SELF%\build\node-%1" ( + pushd "%SELF%\build\" + powershell Expand-Archive -Path %1.zip -DestinationPath "%SELF%\build\" + popd +) else ( + echo "%SELF%\build\node-%1" already exists. +) + +exit /b 0 + + REM =========================================================== :download_node_exe echo :download_node_exe