代码之家  ›  专栏  ›  技术社区  ›  Chad Miller

找不到添加类型错误的元文件

  •  4
  • Chad Miller  · 技术社区  · 16 年前

    我创建了一个实现Microsoft.Data.Schema.ScriptDOM和Microsoft.Data.Schema.ScriptDOM.SQL接口的基本C类。这两个程序集是Visual Studio数据库版本(VSDB)的一部分,也是解析/脚本API的一部分。您可以解析SQL文本并输出格式SQL脚本。有关VSDB程序集的详细信息,请参阅 this blog post . 因为它们是可再发行的,所以我包含了程序集和PowerShell脚本 here :

    #requires -version 2
    
    add-type -path .\Microsoft.Data.Schema.ScriptDom.dll
    add-type -path .\Microsoft.Data.Schema.ScriptDom.Sql.dll
    
    $Source = @"
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Data.Schema.ScriptDom;
    using Microsoft.Data.Schema.ScriptDom.Sql;
    using System.IO;
    
        public class SQLParser
        {
            private IScriptFragment fragment;
    
            public SQLParser(SqlVersion sqlVersion, bool quotedIdentifier, string inputScript)
            {
                switch (sqlVersion)
                {
                    case SqlVersion.Sql80:
                        SQLParser80 (quotedIdentifier, inputScript);
                        break;
                    case SqlVersion.Sql90:
                        SQLParser90 (quotedIdentifier, inputScript);
                        break;
                    case SqlVersion.Sql100:
                        SQLParser100 (quotedIdentifier, inputScript);
                        break;
                }
            }
    
            private void SQLParser100 (bool quotedIdentifier, string inputScript)
            {
                TSql100Parser parser = new TSql100Parser(quotedIdentifier);
                Parse(parser, inputScript);
            }
    
            private void SQLParser90 (bool quotedIdentifier, string inputScript)
            {
                TSql90Parser parser90 = new TSql90Parser(quotedIdentifier);
                Parse(parser90, inputScript);
            }
    
            private void SQLParser80 (bool quotedIdentifier, string inputScript)
            {
                TSql80Parser parser80 = new TSql80Parser(quotedIdentifier);
                Parse(parser80, inputScript);
            }
    
            private void Parse(TSql100Parser parser, string inputScript)
            {
                IList<ParseError> errors;
    
                using (StringReader sr = new StringReader(inputScript))
                {
                    fragment = parser.Parse(sr, out errors);
                }
    
                if (errors != null && errors.Count > 0)
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (var error in errors)
                    {
                        sb.AppendLine(error.Message);
                        sb.AppendLine("offset " + error.Offset.ToString());
                    }
                    throw new ArgumentException("InvalidSQLScript", sb.ToString());
                }
            }
    
            private void Parse(TSql90Parser parser, string inputScript)
            {
                IList<ParseError> errors;
    
                using (StringReader sr = new StringReader(inputScript))
                {
                    fragment = parser.Parse(sr, out errors);
                }
    
                if (errors != null && errors.Count > 0)
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (var error in errors)
                    {
                        sb.AppendLine(error.Message);
                        sb.AppendLine("offset " + error.Offset.ToString());
                    }
                    throw new ArgumentException("InvalidSQLScript", sb.ToString());
                }
            }
    
            private void Parse(TSql80Parser parser, string inputScript)
            {
                IList<ParseError> errors;
    
                using (StringReader sr = new StringReader(inputScript))
                {
                    fragment = parser.Parse(sr, out errors);
                }
    
                if (errors != null && errors.Count > 0)
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (var error in errors)
                    {
                        sb.AppendLine(error.Message);
                        sb.AppendLine("offset " + error.Offset.ToString());
                    }
                    throw new ArgumentException("InvalidSQLScript", sb.ToString());
                }
            }
    
            public IScriptFragment Fragment
            {
                get { return fragment; }
            }
    
    
        }
    "@
    $refs = @("Microsoft.Data.Schema.ScriptDom","Microsoft.Data.Schema.ScriptDom.Sql")
    add-type -ReferencedAssemblies $refs -TypeDefinition $Source -Language CSharpVersion3 -passThru
    

    我正在使用PowerShell v2 add type创建运行时类型。我已经在3台不同的机器上测试了这个脚本。在一台计算机上,脚本在其他两台计算机上按预期工作,将产生以下错误。两个引用的程序集与PowerShell脚本位于同一文件夹中。我做错了什么有什么想法吗?

    PS C:\Users\u00\bin> .\SQLParser.ps1
    Add-Type : (0) : Metadata file 'Microsoft.Data.Schema.ScriptDom.dll' could not be found
    (1) : using System;
    At C:\Users\u00\bin\SQLParser.ps1:125 char:9
    + add-type <<<<  -ReferencedAssemblies $refs -TypeDefinition $Source -Language CSharpVersion3 -passThru
        + CategoryInfo          : InvalidData: (error CS0006: M...ld not be found:CompilerError) [Add-Type], Exception
        + FullyQualifiedErrorId : SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands.AddTypeCommand
    
    Add-Type : (0) : Metadata file 'Microsoft.Data.Schema.ScriptDom.Sql.dll' could not be found
    (1) : using System;
    At C:\Users\u00\bin\SQLParser.ps1:125 char:9
    + add-type <<<<  -ReferencedAssemblies $refs -TypeDefinition $Source -Language CSharpVersion3 -passThru
        + CategoryInfo          : InvalidData: (error CS0006: M...ld not be found:CompilerError) [Add-Type], Exception
        + FullyQualifiedErrorId : SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands.AddTypeCommand
    
    Add-Type : Cannot add type. There were compilation errors.
    At C:\Users\u00\bin\SQLParser.ps1:125 char:9
    + add-type <<<<  -ReferencedAssemblies $refs -TypeDefinition $Source -Language CSharpVersion3 -passThru
        + CategoryInfo          : InvalidData: (:) [Add-Type], InvalidOperationException
        + FullyQualifiedErrorId : COMPILER_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand
    
    3 回复  |  直到 11 年前
        1
  •  6
  •   Jaykul    16 年前

    很简单,一旦你知道;-)

    Max的示例之所以有效,是因为这些程序集位于GAC中,所以可以通过名称引用它们。您的程序集不是,因此需要由路径引用它们。

    您也不需要在顶部添加类型引用,至少对于该脚本不需要这样做——只需将最后几行更改为:

    $PSScriptRoot = (Split-Path $MyInvocation.MyCommand.Path -Parent)
    $refs = @("$PSScriptRoot\Microsoft.Data.Schema.ScriptDom.dll","$PSScriptRoot\Microsoft.Data.Schema.ScriptDom.Sql.dll")
    add-type -ReferencedAssemblies $refs -TypeDefinition $Source -Language CSharpVersion3 -passThru
    
        2
  •  2
  •   Max Trinida    16 年前

    我有一个在PS追踪中使用的样本。这有点基础,但很有效。下面是使用SMO的代码:

    $Assem = ("Microsoft.SqlServer.Smo","Microsoft.SqlServer.ConnectionInfo")
    $Source = @"
    public class MyMSSql
    {
           public static string getEdition(string sqlName)
           {
               string sqlEdition;
               Microsoft.SqlServer.Management.Smo.Server sname = new Microsoft.SqlServer.Management.Smo.Server(sqlName);
               sqlEdition = sname.Information.Edition;
               return sqlEdition;
           }
           public string getSqlEdition(string sqlName)
           {
               string sqlEdition;
               Microsoft.SqlServer.Management.Smo.Server sname = new Microsoft.SqlServer.Management.Smo.Server(sqlName);
               sqlEdition = sname.Information.Edition;
               return sqlEdition;
           }
    
    }
    "@;
    Add-Type -ReferencedAssemblies $Assem -TypeDefinition $Source
    [MyMSSql]::getEdition("MAX-PCWIN1")
    #Developer Edition (64-bit)
    
    $MySQLobj = New-Object MyMSSql
    $MySQLobj.getSqlEdition("MAX-PCWIN1")
    

    希望这能给你一个提示。

    马克斯

        3
  •  2
  •   Keith Hill    16 年前

    如果将vstsdb程序集与脚本放在同一目录中,则不希望在相对路径中使用“.”。“.”将相对于调用脚本的目录。改为尝试类似的操作:

    $ScriptDir = Split-Path $MyInvocation.MyCommand.Path -Parent
    Add-Type -Path "$ScriptDir\Microsoft.Data.Schema.ScriptDom.dll"