Попытка преобразования PowerShell с помощью класса .NET - PullRequest
1 голос
/ 31 мая 2019

Я читал несколько похожих вопросов и ответов, касающихся PS и преобразований типов, но, насколько я понимаю, они не совпадают.

Я пытаюсь использовать классы RMO в скрипте Powershell, но по какой-то причине он считает необходимым преобразование в тот же тип и не может этого сделать.

Код в основном:

$conn = New-Object "Microsoft.SqlServer.Management.Common.ServerConnection" @($server, $dbUsernm, $dbPasswd);

$publicationDb = New-Object "Microsoft.SqlServer.Replication.ReplicationDatabase"
$publicationDb.Name = $dbName;
$publicationDb.ConnectionContext = $conn;

(Подобная ошибка типа возникает, если я пытаюсь использовать конструктор с двумя аргументами.)

Ошибка:

Exception setting "ConnectionContext": "Cannot convert the "(..snip..)" value of type
"Microsoft.SqlServer.Management.Common.ServerConnection" to type "Microsoft.SqlServer.Management.Common.ServerConnection"."

Так что здесь происходит? Он явно пытается преобразовать в те же типы данных. Они не определены в сценариях PowerShell, поэтому не должны ли они отслеживать тип? Я также попытался привести переменную к [Microsoft.SqlServer.Management.Common.ServerConnection] в ее объявлении и / или в наборе вызовов / участников, но безрезультатно.

В случае, если это уместно, я загружаю классы RMO таким способом (который, похоже, является единственным рабочим методом, хотя, как я понимаю, LoadWithPartialName устарел):

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.RMO")

что говорит:

GAC    Version        Location
---    -------        --------
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.SqlServer.RMO\v4.0_14.0.0.0__89845dcd8080cc91\...

Означает ли это, что это v4.x этого класса или это класс .NET 4.x? Если это класс .NET 4.x, это как-то уместно, т. Е. Это проблема для Powershell?

1 Ответ

1 голос
/ 31 мая 2019

TLDR: Сводка по устранению неполадок: @Keilaron ранее Import-Module SqlServer выполнил в сеансе PowerShell, что вызвало странное поведение.

Лично я не был удовлетворен простым перезапуском сеанса PowerShellисправил проблему, так как такого рода ошибки не должны возникать.Когда я продолжил копать, мне показалось, что я обнаружил основную причину и обнаружил, что это большая проблема, которую легко можно пропустить.

Во-первых, код для воспроизведения обнаруженного поведения:

Import-Module SqlServer

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.RMO")

$server = 'MyServer'
$dbuser = 'sa'
$dbPasswd = '1234'
$conn = New-Object "Microsoft.SqlServer.Management.Common.ServerConnection" @($server, $dbUser, $dbPasswd);
$publicationDb = New-Object "Microsoft.SqlServer.Replication.ReplicationDatabase"
$publicationDb.Name = 'RandomDatabase'
$publicationDb.ConnectionContext = $conn;

Происходят две ключевые вещи:

  1. Import-Module SqlServer загружает SqlServer .dll, включенный с модулем, а не Установленные GAC модули.Это сделано специально, так как модуль не зависит от устанавливаемого SQL Server.
  2. Microsoft.SqlServer.Rmo.dll не является частью или загружен с модулем SqlServer, поскольку в SqlServer нет команд репликации.модуль.Таким образом, чтобы использовать команды репликации, мы должны вручную загрузить эти .dll.

Два .dll, которые нам нужны, чтобы прозрачно импортированные Import-Module SqlServer были зависимыми от двух соединений.dll из расположения модуля SqlServer PowerShell:

[System.Reflection.Assembly]::LoadFile('C:\Windows\System32\WindowsPowerShell\v1.0\Modules\SqlServer\Microsoft.SqlServer.ConnectionInfo.dll')
[System.Reflection.Assembly]::LoadFile('C:\Windows\System32\WindowsPowerShell\v1.0\Modules\SqlServer\Microsoft.SqlServer.SqlClrProvider.dll')

-> Примечание: Эти .dll были импортированы как 64 бит .dll s.

RMO .dll, который мы должны были импортировать вручную, поступили из GAC, но по существу:

"C:\Program Files (x86)\Microsoft SQL Server\140\SDK\Assemblies\Microsoft.SqlServer.Rmo.dll"

Примечание: Это 32 бит .dll.Вот почему мы не можем преобразовать "Microsoft.SqlServer.Management.Common.ServerConnection" в тип "Microsoft.SqlServer.Management.Common.ServerConnection".Даже если они одного и того же типа, что и в названии, их разная битность делает их несовместимыми.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...