C# alatt powershell parancs futtatása

C# alatt powershell parancs futtatása
2018-09-20T14:13:39+02:00
2018-09-25T09:53:17+02:00
2022-12-05T14:35:38+01:00
Vazulka#13
Sziasztok

Az alábbi problémám lenne. 
A powershell parancs futtatásához a system.management.Automation dll-t kell használni. (Más módot eddig nem találtam)
Két úton is lehetséges.  
Powershell :

static void ExecutePowerScript(string pPsCommand) { using (PowerShell ps = PowerShell.Create()) { ps.AddScript(pPsCommand); Collection<PSObject> lResults = ps.Invoke(); } }
Runspace 

static void RunScript(string pPsCommand) { Runspace lRunspace = RunspaceFactory.CreateRunspace(); lRunspace.Open(); Pipeline lPipeline = lRunspace.CreatePipeline(); lPipeline.Commands.AddScript(pPsCommand); Collection<PSObject> lResults = lPipeline.Invoke(); lRunspace.Close(); }
Egyiknél sem akar lefordulni a parancs. Letöltöttem a code projectről egy mini form alkalmazást ahol viszont működött. (Telepítés közben a .net framework-öt át kellett állítani) Gondoltam hogy a saját projektemnél is  "letekerem" a projekt > properities > application > target framework-jét 3.0-ra majd visszatekerem jó lesz. És lám jó lett, működik tökéletesen. Viszont ezt a programot több gépre is telepíteni kéne és hogy ez csak így akar működni, nem tűnik stabilnak. Van valami ötletetek, hogy mi lehet a probléma, és hogyan tudnám ezt stabilan alkalmazni?
Előre is köszönöm szépen.
Mutasd a teljes hozzászólást!

  • Helló!

    Ezt a leírást én kipróbáltam, gond nélkül megy Windows 10 1803, .NET 4.7.1-es konzol alkalmazásban.

    Egy buktatót látok, ami esetleg a problémádat okozza: ahogy a leírás is írja, a 3.0-s System.Management.Automation assembly-t innen add hozzá a projecthez:

    C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0

    Lehet, hogy keverednek nálad a PowerShell verziók.

    A példakódot futtatva én végig tudok iterálni a Collection<PSObject>-en.
    Mutasd a teljes hozzászólást!
  • A kollégám gépén is működött. :D Csak simán copy paste, bármelyik reference választásakor is. 
    Van ott is ahol te írtad és van a C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\....
    alatt is. 
    Valami olyan probléma lehet, hogy amikor framework-öt választok akkor nem csak azt állítja át hanem mást is. Most nyomozom, hogy milyen beállítások vannak egy új console projektnél, és mi változik, ha le, majd vissza állítom a framework-öt. Gyanítom valami alap beállítás az én visual studiomban nem kóser.
    Mutasd a teljes hozzászólást!
  • Szerintem kezdetnek fogj egy új projectet és próbáld újra! Ne váltogass a Framework runtime-ok között (2.0-4.0)! Az biztos, hogy ott minden referencia meg fog változni.

    Mi a konkrét hiba a fenti teszt kódnál? Exception? Üres a Collection<PSObject> eredmény?
    Mutasd a teljes hozzászólást!
  • Is is a powershellnél üres collection, a Runspece-nél exeption melynek message-e:
    The term 'export-dhcpserver' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    Mutasd a teljes hozzászólást!
  • Megtaláltam mit állított át, de így még X-aktásabb. :)

    Valamiért, amikor console (.net framework) projektet hozok létre, akkor a target platform bár any CPU, de be van pipálva a prefer-32 bit. Ha állítgatom a framework-öt eltűnik a pipa. Kipróbáltam egy új projektnél, működött framework állítgatás nélkül, csak ki kellett vennem a pipát. 
    1. Miért van "gyárilag" bepipálva? 
    2. Hány assembly fog rosszul működni emiatt?
    Mutasd a teljes hozzászólást!
  • Nem világos, hogy pontosan mi a tapasztalatod. Valahogy összeszedettebben kéne leírnod, pl. így:

    .NET 3.5-ös project, Prefer 32-bit bepipálva - működik
    .NET 4.7.1-es project, Prefer 32-bit bepipálva - nem működik

    De nem hiszem, hogy a problémádhoz ennek köze van. Nálam mindegy, be van-e pipálva (ha be van, akkor 64 bites rendszeren is 32 bites kódot fordít), de direkt kipróbáltam a Platform targetet explicit x86-ra és x64-re is állítva, hogy van-e probléma. Nincs, működik mindenhogyan.

    Még egyszer a tesztkörnyezet: Windows 10 1803 64 bit, .NET 4.7.1-es konzol alkalmazás, linkelt példakód, VS 15.8.5, minden default-on.

    Próbáld így ki! Ha így nem működik, másik gépen viszont igen, akkor valami helyi problémád van -> újratelepítés.
    Mutasd a teljes hozzászólást!
  • Tesztkörnyezet
    - Windows 10 Version 1803 x64
    - VS Enterprise 2017 15.8.2

    Tesztkód:

    using System.Management.Automation; using System.Management.Automation.Runspaces; using System.Collections.ObjectModel; namespace ConsoleApp1 { class Program { static void RunScript(string pPsCommand) { Runspace lRunspace = RunspaceFactory.CreateRunspace(); lRunspace.Open(); Pipeline lPipeline = lRunspace.CreatePipeline(); lPipeline.Commands.AddScript(pPsCommand); Collection<PSObject> lResults = lPipeline.Invoke(); lRunspace.Close(); } static void Main(string[] args) { string lText = "export-dhcpserver -file "c:\ProgramData\LeaseReader\lease_dump.txt" -leases -force"; RunScript(lText); } } }
    .NET 4.7.2-es project, Prefer 32-bit bepipálva - nem működik
    (exception: System.Management.Automation.CommandNotFoundException: 'The term 'export-dhcpserver' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.')
    .NET 4.7.2-es project, Prefer 32-bit nincs bepipálva - működik
    Mutasd a teljes hozzászólást!
  • Bár látom, hogy ennek működnie kéne Win10 alatt, de a PowerShell ablak nálam sem ismeri az export-dhcpserver parancsot (és semmilyen DHCP specifikusat). Ami logikus, mivel biztosan nincs a Win10-em DHCP szervernek konfigurálva. A te exception-öd üzetetét kapom, ha megpróbálom futtatni.

    Kipróbálnád a leírásban szereplő példakódot? Vagy valami standard PowerShell parancsot, pl. get-service?

    Muszáj lenne különbséget tenni aközött, hogy le tudsz-e egyáltalán futtatni egy PS-scriptet és aközött, hogy az fut-e hibára.
    Mutasd a teljes hozzászólást!
  • A lokális gép, amin fejlesztek valóban nem szerver gép, így maga a parancs "értelmetlen".
    A szervergépen természetesen megteszi amit kell. A parancs jól működik megfelelő környezetben.
    Viszont a lokális gépen (ami nem szerver) powershell 3.0 ise alatt lefut és megnyit egy popup ablakot hogy mivel szeretném az ominózus file-t megnyitni. Szóval ez lenne az elvárt működés lokális nem szerver környezetben. 
    Na mármost ha ki van pipálva exception-t dob, ha nincs akkor hozza az elvárt működést. :)
    Mutasd a teljes hozzászólást!
  • Kipróbálnád a leírásban szereplő példakódot? Vagy valami standard PowerShell parancsot, pl. get-service?
    Mutasd a teljes hozzászólást!
  • Kipróbálnád a leírásban szereplő példakódot? Vagy valami standard PowerShell parancsot, pl. get-service?

    A leírásban szereplő példakódommal a dhcp parancs nem fut le ha a prefer 32 biten van,de a get service parancs viszont simán lefut. 
    Ma tesztelve lett a szerver gépen. Le kellett venni a target framworköt 4.5 re és tökéletesen működik.
    Elképzelhető, hogy  a system.management.automation dll egészen máshogyan reagál egy powershellen keresztüli dhcp parancsra más target framework, és platform alatt?
    Mutasd a teljes hozzászólást!
  • Részben reprodukáltam a problémát.

    Csináltam egy dummy dhcp.cmd file-t. De nálam nem számít, hogy .NET 4.5 v. 4.7.2 a target. Külső file futtatása (dhcp.cmd) nem működik, ha 64 bites rendszer alatt 32 bitesre fordítom az alkalmazást (a prefer 32-bit ugye ezt csinálja). A beépített parancsnak (get-service) viszont mindegy, az bárhogyan működik.

    Furcsa, hogy egyáltalán nálad működni kezdett. Olyasmit el tudok képzelni, hogy a 64 bites rendszeren az Export-DhcpServer kódja 64 bites (nem világos, hogy pontosan mi tartalmazza ezt), és automation.dll-t használva, 32 bites alkalmazásból azt így nem képes futtatni, mivel nem keverheted a 32 és 64 bites kódot egy processen belül.

    Viszont akkor miért működik, ha .NET 4.5-re fordítod? Ez viszont logikátlan. Nincs itt valami tévedés? Hagyd a prefer kapcsolót kikapcsolva és próbáld inkább a platform target-et explicit x86-ra vagy x64-re állítani.

    Mindenesetre pont azért kértelek beépített parancs hívására, hogy egyértelműen kiderüljön: nem a hívó kóddal van probléma, hanem a hívottal.
    Mutasd a teljes hozzászólást!
  • Oké a végén leesett, hogy a leírás alatti példakód alatt nem az én példakódomat értetted. :)

    szóval 
    1. teszt eset: Lokál gép win 10 vs enterprise.
    Új project target framework 4.7.2 (valamiért a prefer 32 bit defaultként bepipálva)
    Get service lefut
    dhcp nem fut ominózus exception.
    1.2 teszt eset ua. gép prefer 32 bit nincs pipa
    Get service lefut 
    dhcp lefut
    2. teszt eset: kolléga gépe   Lokál gép win 10 vs enterprise.
    Új project target framework 4.7.2 (prefer 32 bit Nincs bepipálva)
    Get service lefut 
    dhcp lefut
    3 teszt eset: virtuális gép win 10 vs community 15.5.2
    Teljes solution svnről sln megnyit.
    Target framework 4.6.1 (nincs újabb telepítve még) (prefer 32 bit defaultként Nincs bepipálva)
    Get service lefut 
    dhcp NEM FUT 

    3....n teszt eset ua. gép 
    Target framework 3.0 - 4.6.1 (prefer 32 bit be/ki pipálva) Rebuild
    Get service lefut 
    dhcp NEM FUT
    Az itteni powershell sem tudja futtatni a scriptet.
    4 teszt eset
    szerver gép program telepítve config file beállítva (csak path -okat tartalmaz)
    dhcp NEM FUT
    -side by side config hiba
    4.2 teszt eset Target framwork átállítva 4.5 re rebuild, commit, újrarak
    tökéletesen működik :)

    Szerintem -Javíts(atok) ki ha tévednék- A powershell a commandokat másképpen kezeli attól függően hogy milyen platformról érkezik. A PS3.0 -nál ha x platformról érkezik - lehet kimaradt az exception kidolgozása-, a commandban tovább lép. Mivel nálam az egy file létrehozása ezért ugrik fel a file opener popup ablak, és tovább megy a program. Ám ha x-en kívüli platformról jön és/vagy nincs telepítve a 3.0 csak a 2.0 akkor az eredeti ágon exceptionra fut, és leállítja a futást.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd