Попытка преобразования PowerShell с классом .NET

Я прочитал несколько похожих вопросов и ответов относительно 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\...

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

Как вы загружаете ConnectionInfo? то есть [System.Reflection.Assembly]::LoadWithPartialName("Microsoft‌​.SqlServer.Connectio‌​nInfo")

HAL9256 31.05.2019 02:01

Он явно не загружен. Должен ли я также загружать зависимости вручную?

Keilaron 31.05.2019 02:03

Я попытался добавить его; Он загружается, но я все еще получаю то же исключение.

Keilaron 31.05.2019 15:47

Извините, я не могу воспроизвести проблему. Мне пришлось загрузить обе сборки, чтобы код заработал. Я бы попробовал закрыть PowerShell и снова открыть его, а также попытаться явно загрузить .dll, потому что это может быть несоответствие версии, например. загрузка с частичным именем — это загрузка из GAC, и то, что зарегистрировано в GAC. то есть: загрузить [System.Reflection.Assembly]::LoadFile('C:\Program Files\Microsoft SQL Server\140\SDK\Assemblies\Microsoft.SqlServer.Replication.dl‌​l')

HAL9256 31.05.2019 17:00

Подожди - твой находится в Program Files. Вы делаете это в системе, где установлен MS SQL? Идея состоит в том, чтобы иметь возможность делать это удаленно из агента CI, поэтому я надеюсь, что MS SQL не нужно устанавливать локально. FWIW моя версия для ConnectionInfo говорит 2.0.50727..

Keilaron 31.05.2019 17:02

Да, мне пришлось, это было единственное место, где я мог загрузить правильную комбинацию сборок. Не могли бы вы подтвердить, что можете запустить $conn.connect(), а затем $conn.InUse вернётся True?

HAL9256 31.05.2019 17:09

Да и с самим подключением все в порядке. И IsOpen, и InUse верны после подключения.

Keilaron 31.05.2019 17:13

Давайте продолжить обсуждение в чате.

HAL9256 31.05.2019 17:26
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
8
48
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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.

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". Несмотря на то, что они одного типа по названию, их разная разрядность делает их несовместимыми.

В частности: я не знал, что импорт модуля повлияет на консоль, запускающую его после завершения выполнения скрипта, что это вызовет конфликты версий (или, по крайней мере, я предполагаю, что это происходит), несмотря на явную загрузку других сборок впоследствии, и так далее. Спасибо еще раз за помощь!

Keilaron 31.05.2019 18:17

Я еще немного покопался, и я считаю, что обнаружил корень проблемы. Смотрите мои правки выше.

HAL9256 31.05.2019 20:02

Я ценю это, хотя оказывается, что тот факт, что я игнорировал, что у меня не было репликации, является проблемой: он пытается загрузить его только после того, как я вызываю .Script() для объекта публикации. Так что мне придется найти какой-то способ получить это без установки MS SQL (желательно).

Keilaron 31.05.2019 20:19

Другие вопросы по теме