Poniższy kod programu PowerShell
#Get a server object which corresponds to the default instance
$srv = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Server
... rest of the script ...
Daje następujący komunikat o błędzie:
New-Object : Cannot find type [Microsoft.SqlServer.Management.SMO.Server]: make sure
the assembly containing this type is loaded.
At C:\Users\sortelyn\ ... \tools\sql_express_backup\backup.ps1:6 char:8
+ $srv = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Server
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidType: (:) [New-Object], PSArgumentException
+ FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand
Każda odpowiedź w internecie pisze, że muszę załadować montaż - na pewno mogę to wyczytać z komunikatu błędu :-) - pytanie brzmi:
Jak ładujesz assembler i uruchamiasz skrypt?
powershell
powershell-3.0
Baxter
źródło
źródło
This API is now obsolete.
Oczywiście to nie powstrzymuje ludzi przed używaniem go.LoadWithPartialName
zostało wycofane, przyczyny (opisane w blogs.msdn.com/b/suzcook/archive/2003/05/30/57159.aspx ) wyraźnie nie dotyczą interaktywnej sesji programu Powershell. Proponuję dodać uwagę, że API jest dobre do interaktywnego użycia Powershell.źródło
Out-Null
jeśli nie chcesz, aby GAC odbijał echo.Add-Type -Path [...]; if (!$?) { Add-Type -Path [...] } elseif [...]
.Większość ludzi już wie, że
System.Reflection.Assembly.LoadWithPartialName
jest to przestarzałe, ale okazuje się, żeAdd-Type -AssemblyName Microsoft.VisualBasic
nie zachowuje się dużo lepiej niżLoadWithPartialName
:Microsoft twierdzi, że faktycznie powinieneś zrobić coś takiego:
Lub, jeśli znasz ścieżkę, coś takiego:
Ta długa nazwa nadana zespołowi jest znana jako silna nazwa , która jest unikalna zarówno dla wersji, jak i zestawu, a czasami jest również nazywana pełną nazwą.
Ale to pozostawia kilka pytań bez odpowiedzi:
Jak określić silną nazwę tego, co faktycznie jest ładowane w moim systemie z podaną nazwą częściową?
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).Location;
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).FullName;
Te też powinny działać:
Jeśli chcę, aby mój skrypt zawsze korzystał z określonej wersji pliku .dll, ale nie mam pewności, gdzie jest zainstalowany, w jaki sposób mogę określić, jaka jest silna nazwa z pliku .dll?
[System.Reflection.AssemblyName]::GetAssemblyName($Path).FullName;
Lub:
Jeśli znam silną nazwę, jak określić ścieżkę .dll?
[Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a').Location;
I w podobny sposób, jeśli znam nazwę typu tego, czego używam, skąd mam wiedzieć, z jakiego zespołu pochodzi?
[Reflection.Assembly]::GetAssembly([Type]).Location
[Reflection.Assembly]::GetAssembly([Type]).FullName
Jak mogę sprawdzić, jakie zestawy są dostępne?
Proponuję moduł GAC PowerShell .
Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName
działa całkiem nieźle.Add-Type
używa?To jest trochę bardziej złożone. Mogę opisać, jak uzyskać do niego dostęp dla dowolnej wersji programu PowerShell z reflektorem .Net (zobacz aktualizację poniżej dotyczącą programu PowerShell Core 6.0).
Najpierw dowiedz się, z której biblioteki
Add-Type
pochodzi:Otwórz wynikową bibliotekę DLL za pomocą reflektora. Użyłem ILSpy za to, bo to FLOSS, ale wszelkie C # reflektor powinien działać. Otwórz tę bibliotekę i zajrzyj do środka
Microsoft.Powershell.Commands.Utility
. PodMicrosoft.Powershell.Commands
spodem powinno byćAddTypeCommand
.W kodzie witryny, że znajduje się prywatny klasy
InitializeStrongNameDictionary()
. Zawiera słownik, który odwzorowuje krótkie nazwy na silne nazwy. W bibliotece, którą przeglądałem, jest prawie 750 pozycji.Aktualizacja: teraz, gdy program PowerShell Core 6.0 jest oprogramowaniem typu open source. W przypadku tej wersji możesz pominąć powyższe kroki i zobaczyć kod bezpośrednio online w ich repozytorium GitHub . Nie mogę jednak zagwarantować, że ten kod pasuje do dowolnej innej wersji programu PowerShell.
źródło
Add-Type
lubLoadWithPartialName()
, ale musisz mieć świadomość, że ta pierwsza nie będzie w 100% spójna we wszystkich wersjach, a druga jest przestarzałą metodą. Innymi słowy, .Net chce, abyś dbał o wersję biblioteki, którą ładujesz.Add-Type -Path
, który jest drugim wymienionym kodem lubAssembly.LoadFrom()
który rozwiązuje za Ciebie zależności (i, o ile wiem, tegoAdd-Type -Path
używa). Jedyny przypadek, którego powinieneś używać,Assembly.LoadFile()
to ładowanie wielu zestawów, które mają tę samą tożsamość, ale różne ścieżki. To dziwna sytuacja.Jeśli chcesz załadować zestaw bez blokowania go podczas trwania sesji programu PowerShell , użyj tego:
Gdzie
$storageAssemblyPath
jest ścieżka pliku twojego zespołu.Jest to szczególnie przydatne, jeśli chcesz wyczyścić zasoby podczas sesji. Na przykład w skrypcie wdrażania.
źródło
Oto kilka postów na blogu z licznymi przykładami sposobów ładowania zestawów w programie PowerShell w wersji 1, 2 i 3.
Sposoby obejmują:
v1.0 Jak ładować zestawy .NET w sesji programu PowerShell
v2.0 przy użyciu kodu CSharp (C #) w skryptach programu PowerShell 2.0
v3.0 Korzystanie z zestawów .NET Framework w programie Windows PowerShell
źródło
Możesz załadować cały zestaw * .dll za pomocą
źródło
Żadna z odpowiedzi mi nie pomogła, więc publikuję rozwiązanie, które działało dla mnie, wystarczyło zaimportować moduł SQLPS, zdałem sobie z tego sprawę, gdy przypadkowo uruchomiłem polecenie Restore-SqlDatabase i zacząłem działać, co oznacza, że zestaw był w jakiś sposób przywoływany w tym module.
Po prostu biegnij:
Uwaga: dziękujemy Jasonowi za zauważenie, że SQLPS jest przestarzały
zamiast tego biegnij:
lub
źródło
sqlps
sqlserver
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
pracował dla mnie.źródło
Możesz użyć
LoadWithPartialName
. Jednak, jak powiedzieli, jest to przestarzałe.Rzeczywiście możesz się zgodzić
Add-Type
i oprócz innych odpowiedzi, jeśli nie chcesz określać pełnej ścieżki do pliku .dll, możesz po prostu zrobić:Mnie zwróciło to błąd, ponieważ nie mam zainstalowanego SQL Server (chyba), jednak z tym samym pomysłem udało mi się załadować zestaw Windows Forms:
Dokładną nazwę zestawu należącego do określonej klasy można znaleźć w witrynie MSDN:
źródło
Upewnij się, że poniższe funkcje są zainstalowane w kolejności
Konieczne może być również załadowanie
źródło
Dodaj odniesienia do zestawów u góry.
źródło