Ошибка типа мета-файла не найдена - PullRequest
4 голосов
/ 29 октября 2009

Я создал базовый класс C #, который реализует интерфейс Microsoft.Data.Schema.ScriptDom и Microsoft.Data.Schema.ScriptDom.Sql. Эти две сборки являются частью Visual Studio Database Edition (VSDB) и являются API-интерфейсом для синтаксического анализа / создания сценариев. Вы можете анализировать текст SQL и выводить сценарий формата SQL. Для получения дополнительной информации о сборках VSDB см. этот блог . Поскольку они распространяются, я включил обе сборки и скрипт PowerShell здесь :

#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 ]

6 голосов
/ 29 октября 2009

Довольно просто, как только вы знаете; -)

Пример Макса работает, потому что эти сборки находятся в GAC, поэтому на них можно ссылаться по имени. Ваши сборки не являются таковыми, поэтому на них нужно ссылаться по пути.

Вам также не нужны ссылки Add-Type вверху, по крайней мере, не для этого скрипта - просто измените последние пару строк на:

$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 голосов
/ 29 октября 2009

У меня есть сэмпл, который я использую на нашем треке 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")

Надеюсь, это даст вам подсказку.

Макс

2 голосов
/ 29 октября 2009

Если вы поместите сборки VSTSDB в тот же каталог, что и скрипт, тогда вы не захотите использовать "." в относительном пути. "" будет относительно каталога, в который вызывается скрипт. Попробуйте что-то вроде этого:

$ScriptDir = Split-Path $MyInvocation.MyCommand.Path -Parent
Add-Type -Path "$ScriptDir\Microsoft.Data.Schema.ScriptDom.dll"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...