Powershell: Type definition fails in Powershell 7.0.0-preview.5

Created on 19 Nov 2019  Â·  10Comments  Â·  Source: PowerShell/PowerShell

 $PSVersionTable

```none
Name Value
---- -----
PSVersion 7.0.0-preview.5
PSEdition Core
GitCommitId 7.0.0-preview.5
OS Microsoft Windows 10.0.18362
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0


# Steps to reproduce

```powershell
Add-Type -TypeDefinition @"
using System;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Text;

namespace Helper.Sql
{
    public class SqlCommandExt<T>
    {
        public SqlCommandExt() {;}
        public SqlParameter[] AddArrayParameters(SqlCommand cmd, IEnumerable<T> values, string paramNameRoot, int start = 1, string separator = ", ")
        {
            var parameters = new List<SqlParameter>();
            var parameterNames = new List<string>();
            var paramNbr = start;
            foreach (var value in values)
            {
                var paramName = string.Format("@{0}{1}", paramNameRoot, paramNbr++);
                parameterNames.Add(paramName);
                parameters.Add(cmd.Parameters.AddWithValue(paramName, value));
            }

            cmd.CommandText = cmd.CommandText.Replace("@@" + paramNameRoot, string.Join(separator, parameterNames));

            return parameters.ToArray();
        }
    }
}
"@ -ReferencedAssemblies System.Data

Expected behavior

Type definition succeeds. As it does with all previous versions.

Actual behavior

Errors:
Add-Type: (10,50): error CS1069: The type name 'SqlCommand' could not be found in the namespace 'System.Data.SqlClient'. This type has been forwarded to assembly 'System.Data.SqlClient, Version=4.6.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' Consider adding a reference to that assembly.
        public SqlParameter[] AddArrayParameters(SqlCommand cmd, IEnumerable<T> values, string paramNameRoot, int start = 1, string separator = ", ")
                                                 ^

Add-Type: (10,16): error CS1069: The type name 'SqlParameter' could not be found in the namespace 'System.Data.SqlClient'. This type has been forwarded to assembly 'System.Data.SqlClient, Version=4.6.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' Consider adding a reference to that assembly.
        public SqlParameter[] AddArrayParameters(SqlCommand cmd, IEnumerable<T> values, string paramNameRoot, int start = 1, string separator = ", ")
               ^

Add-Type: (12,39): error CS1069: The type name 'SqlParameter' could not be found in the namespace 'System.Data.SqlClient'. This type has been forwarded to assembly 'System.Data.SqlClient, Version=4.6.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' Consider adding a reference to that assembly.
            var parameters = new List<SqlParameter>();
                                      ^

Add-Type: Cannot add type. Compilation errors occurred.

Environment data


Issue-Question Resolution-Answered

Most helpful comment

Yeah, looks like System.Data.SqlClient references System.Runtime, Version=4.2.2.0 when PS itself references 4.2.1.0. You can get it to work by adding System.Runtime to the referenced assemblies and adding -IgnoreWarnings and -WarningAction None.

Add-Type needs some work when it comes to references, especially around version conflicts.

Here's a smaller repro that works:

Add-Type -WarningAction Ignore -IgnoreWarnings -ReferencedAssemblies System.Runtime, System.Data, System.Data.SqlClient -TypeDefinition '
        using System;
        using System.Data.SqlClient;
        public static class Testing {
            public static SqlCommand DoSomething() => throw new System.NotImplementedException();
        }'

All 10 comments

@reflectedobject System.Data isn't a pre-loaded assembly. You'll need to add -ReferencedAssemblies 'System.Data to the Add-Type command call to load it in and use the types it contains, which include the System.Data.SqlClient namespace. 🙂

That is exactly what I am doing - please check the last line of my posted code.

"@ -ReferencedAssemblies System.Data'

The code works fine with Powershell for Windows but fails with the Powershell 7 preview (5).

@reflectedobject System.Data isn't a pre-loaded assembly. You'll need to add -ReferencedAssemblies 'System.Data to the Add-Type command call to load it in and use the types it contains, which include the System.Data.SqlClient namespace. 🙂

You're right, sorry, I didn't see that one.

I suspect the issue may come either from where the System.Data assemblies are installed (possibly in a location Windows PowerShell reaches by default, but must be targeted specifically for PS Core), or how they're built. If the System.Data assemblies depend on classes only available in .NET Framework, they may not be able to be loaded under .NET Core.

@potatoqualitee have you folx looked at using the System.Data assembly in PowerShell Core/7 thus far? Perhaps you might be more familiar working with this side of things than some of the other folx in the repo here. 🙂

SqlCommand is technically in the assembly System.Data.SqlClient now. That said, the System.Data assembly does have a TypeForwardedTo pointing to the correct assembly, so maybe that should be accounted for in some way by Add-Type.

SqlCommand is technically in the assembly System.Data.SqlClient now. That said, the System.Data assembly does have a TypeForwardedTo pointing to the correct assembly, so maybe that should be accounted for in some way by Add-Type.

Any pointer on how that can be accomplished? Never had to deal with TypeForwardTo before.

Short-term you should be able to just reference Systom.Data.SqlClient instead in the -ReferencedAssemblies

Long term we probably need to try to determine how to handle that in Add-Type itself so that forwarded types are automatically picked up.

Thanks for all the feedback. I have tried a few referenced assembly variants and got the following:

Add-Type -TypeDefinition @" … omitted as same as at beginning of post ..."@ -ReferencedAssemblies System.Data.SqlClient

Give another set of hard to decrypt messages (for me at least).
It appears to be some ambiguity/conflict for the System.Runtime Assembly.

In the interim I have compiled the code into a .NET Core library and load the DLL rather than the script included code.

I'd be grateful for any pointers to get it to work like it did.

Add-Type: error CS1702: Assuming assembly reference 'System.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'System.Data.SqlClient' matches identity 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy
Add-Type: error CS1702: Assuming assembly reference 'System.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'System.Data.SqlClient' matches identity 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy
Add-Type: (27,34): error CS0246: The type or namespace name 'List<>' could not be found (are you missing a using directive or an assembly reference?)
            var parameters = new List<SqlParameter>();
                                 ^

Add-Type: error CS1702: Assuming assembly reference 'System.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'System.Data.SqlClient' matches identity 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy
Add-Type: (28,38): error CS0246: The type or namespace name 'List<>' could not be found (are you missing a using directive or an assembly reference?)
            var parameterNames = new List<string>();
                                     ^

Add-Type: (34,47): error CS0012: The type 'DbParameterCollection' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Data.Common, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
                parameters.Add(cmd.Parameters.AddWithValue(paramName, value));
                                              ^

Add-Type: (34,32): error CS1702: Assuming assembly reference 'System.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'System.Data.SqlClient' matches identity 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy
                parameters.Add(cmd.Parameters.AddWithValue(paramName, value));
                               ^

Add-Type: error CS1702: Assuming assembly reference 'System.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'System.Data.SqlClient' matches identity 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy       Add-Type: error CS1702: Assuming assembly reference 'System.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'System.Data.SqlClient' matches identity 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy       Add-Type: Cannot add type. Compilation errors occurred.

Interesting. Not sure about the version # mismatches there, but it looks like you need -ReferencedAssemblies System.Data.Common, System.Data.SqlClient and then also just check your using statements; List<> is in the Systems.Collection.Generic namespace, so make sure you have that in your using statements. 🙂

Yeah, looks like System.Data.SqlClient references System.Runtime, Version=4.2.2.0 when PS itself references 4.2.1.0. You can get it to work by adding System.Runtime to the referenced assemblies and adding -IgnoreWarnings and -WarningAction None.

Add-Type needs some work when it comes to references, especially around version conflicts.

Here's a smaller repro that works:

Add-Type -WarningAction Ignore -IgnoreWarnings -ReferencedAssemblies System.Runtime, System.Data, System.Data.SqlClient -TypeDefinition '
        using System;
        using System.Data.SqlClient;
        public static class Testing {
            public static SqlCommand DoSomething() => throw new System.NotImplementedException();
        }'

This issue has been marked as answered and has not had any activity for 1 day. It has been closed for housekeeping purposes.

Was this page helpful?
0 / 5 - 0 ratings