From b5255feca9723db1e49cc761933b40c006c1f086 Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Fri, 20 Sep 2019 16:00:54 -0700 Subject: [PATCH 1/6] Make Add-Type usable in application that hosts PowerShell --- .../commands/utility/AddType.cs | 2 +- test/hosting/test_HostingBasic.cs | 32 +++++++++++++++++++ tools/packaging/packaging.psm1 | 10 ++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs index 4e6fc676432..a66ad20c847 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs @@ -599,7 +599,7 @@ protected override void EndProcessing() // We now ship .Net Core's reference assemblies with PowerShell, so that Add-Type can work // in a predictable way and won't be broken when we move to newer version of .NET Core. // The reference assemblies are located at '$PSHOME\ref'. - private static readonly string s_netcoreAppRefFolder = PathType.Combine(PathType.GetDirectoryName(typeof(PSObject).Assembly.Location), "ref"); + private static readonly string s_netcoreAppRefFolder = PathType.Combine(PathType.GetDirectoryName(Assembly.GetEntryAssembly().Location), "ref"); private static readonly string s_frameworkFolder = PathType.GetDirectoryName(typeof(object).Assembly.Location); // These assemblies are always automatically added to ReferencedAssemblies. diff --git a/test/hosting/test_HostingBasic.cs b/test/hosting/test_HostingBasic.cs index 164f1f02aae..7968621b731 100644 --- a/test/hosting/test_HostingBasic.cs +++ b/test/hosting/test_HostingBasic.cs @@ -139,5 +139,37 @@ public static void TestCommandFromNative() File.Delete(target); } } + + [Fact] + public static void TestAddType() + { + string code = @" + using System; + public class Foo + { + public Foo(string name, string path) + { + this.Name = name; + this.Path = path; + } + + public string Name; + public string Path; + } + "; + + using (System.Management.Automation.PowerShell ps = System.Management.Automation.PowerShell.Create()) + { + ps.AddCommand("Add-Type").AddParameter("TypeDefinition", code).Invoke(); + ps.Commands.Clear(); + + var results = ps.AddScript("[Foo]::new('Joe', 'Unknown')").Invoke(); + Assert.Single(results); + + dynamic foo = results[0]; + Assert.Equal("Joe", foo.Name); + Assert.Equal("Unknown", foo.Path); + } + } } } diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1 index f574fa2ce9c..9d644a797d9 100644 --- a/tools/packaging/packaging.psm1 +++ b/tools/packaging/packaging.psm1 @@ -1561,6 +1561,16 @@ function New-ILNugetPackage CreateNugetPlatformFolder -Platform 'unix' -PackageRuntimesFolder $packageRuntimesFolderPath -PlatformBinPath $LinuxFxdBinPath } + if ($file -eq "Microsoft.PowerShell.SDK.dll") + { + # Copy the '$PSHome\ref' folder to the NuGet package, so 'dotnet publish' can deploy the 'ref' folder to the publish folder. + # This is to make 'Add-Type' work in application that hosts PowerShell. + + $contentFolder = New-Item (Join-Path $filePackageFolder "contentFiles\any\any") -ItemType Directory -Force + $dotnetRefAsmFolder = Join-Path -Path $WinFxdBinPath -ChildPath "ref" + Copy-Item -Path $dotnetRefAsmFolder -Destination $contentFolder -Recurse -Force + } + #region nuspec # filed a tracking bug for automating generation of dependecy list: https://github.com/PowerShell/PowerShell/issues/6247 $deps = [System.Collections.ArrayList]::new() From 01a702b692383ff9ccfad1d57c6113b22e9500eb Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Mon, 23 Sep 2019 10:55:21 -0700 Subject: [PATCH 2/6] Fix the failing tests --- .../commands/utility/AddType.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs index a66ad20c847..f0aab37b9ba 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs @@ -598,8 +598,19 @@ protected override void EndProcessing() // We now ship .Net Core's reference assemblies with PowerShell, so that Add-Type can work // in a predictable way and won't be broken when we move to newer version of .NET Core. - // The reference assemblies are located at '$PSHOME\ref'. - private static readonly string s_netcoreAppRefFolder = PathType.Combine(PathType.GetDirectoryName(Assembly.GetEntryAssembly().Location), "ref"); + // The reference assemblies are located at '$PSHOME\ref' for pwsh. + // + // For applications that host PowerShell, the 'ref' folder will be deployed to the 'publish' + // folder, not where 'System.Management.Automation.dll' is located. So here we should use + // the entry assembly's location to construct the path to the 'ref' folder. + // For pwsh, the entry assembly is 'pwsh.dll', so the entry assembly's location is still + // $PSHOME. + // However, 'Assembly.GetEntryAssembly()' returns null when the managed code is called from + // unmanaged code (PowerShell WSMan remoting scenario), so in that case, we continue to use + // the location of 'System.Management.Automation.dll'. + private static readonly string s_netcoreAppRefFolder = PathType.Combine( + PathType.GetDirectoryName( + (Assembly.GetEntryAssembly() ?? typeof(PSObject).Assembly).Location), "ref"); private static readonly string s_frameworkFolder = PathType.GetDirectoryName(typeof(object).Assembly.Location); // These assemblies are always automatically added to ReferencedAssemblies. From 7559e99d5eef167d4599a23b18fc40570fec8db9 Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Mon, 23 Sep 2019 11:06:44 -0700 Subject: [PATCH 3/6] Rename the test --- test/hosting/test_HostingBasic.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hosting/test_HostingBasic.cs b/test/hosting/test_HostingBasic.cs index 7968621b731..36ed1b922fe 100644 --- a/test/hosting/test_HostingBasic.cs +++ b/test/hosting/test_HostingBasic.cs @@ -141,7 +141,7 @@ public static void TestCommandFromNative() } [Fact] - public static void TestAddType() + public static void TestAddTypeCmdletInHostScenario() { string code = @" using System; From ba4074f6f15e69c39f17b949ba19aba9b48399fe Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Mon, 23 Sep 2019 11:11:31 -0700 Subject: [PATCH 4/6] Resovle CodeFactor issuese --- .../commands/utility/AddType.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs index f0aab37b9ba..0f795cb2a23 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs @@ -596,7 +596,7 @@ protected override void EndProcessing() #region LoadAssembly - // We now ship .Net Core's reference assemblies with PowerShell, so that Add-Type can work + // We now ship .NET Core's reference assemblies with PowerShell, so that Add-Type can work // in a predictable way and won't be broken when we move to newer version of .NET Core. // The reference assemblies are located at '$PSHOME\ref' for pwsh. // @@ -610,7 +610,10 @@ protected override void EndProcessing() // the location of 'System.Management.Automation.dll'. private static readonly string s_netcoreAppRefFolder = PathType.Combine( PathType.GetDirectoryName( - (Assembly.GetEntryAssembly() ?? typeof(PSObject).Assembly).Location), "ref"); + (Assembly.GetEntryAssembly() ?? typeof(PSObject).Assembly).Location), + "ref"); + + // Path to the folder where .NET Core runtime assemblies are located. private static readonly string s_frameworkFolder = PathType.GetDirectoryName(typeof(object).Assembly.Location); // These assemblies are always automatically added to ReferencedAssemblies. From f23900374e71ded1bba713760e4d850ef1677608 Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Tue, 24 Sep 2019 10:25:05 -0700 Subject: [PATCH 5/6] Add comment to the Add-Type hosting test --- test/hosting/test_HostingBasic.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/hosting/test_HostingBasic.cs b/test/hosting/test_HostingBasic.cs index 36ed1b922fe..59bbad97f42 100644 --- a/test/hosting/test_HostingBasic.cs +++ b/test/hosting/test_HostingBasic.cs @@ -140,6 +140,9 @@ public static void TestCommandFromNative() } } + /// + /// Reference assemblies should be handled correctly so that Add-Type works in the hosting scenario + /// [Fact] public static void TestAddTypeCmdletInHostScenario() { From f1a4eb425125b795ce75a6b03f4398e739120238 Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Tue, 24 Sep 2019 10:27:51 -0700 Subject: [PATCH 6/6] Address CodeFactor issue --- test/hosting/test_HostingBasic.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hosting/test_HostingBasic.cs b/test/hosting/test_HostingBasic.cs index 59bbad97f42..b16cd5ba0ec 100644 --- a/test/hosting/test_HostingBasic.cs +++ b/test/hosting/test_HostingBasic.cs @@ -141,7 +141,7 @@ public static void TestCommandFromNative() } /// - /// Reference assemblies should be handled correctly so that Add-Type works in the hosting scenario + /// Reference assemblies should be handled correctly so that Add-Type works in the hosting scenario. /// [Fact] public static void TestAddTypeCmdletInHostScenario()