Question [Astuce] Batch et gestion de paramètres

Plus d'informations
il y a 11 ans 6 mois #12745 par Laurent Dardenne
Salut,
une petite astuce sur le passage de paramètres entre une application externe et Powershell.
Le problème qu'on peut rencontrer est du au parseur de Powershell, car soit celui-ci interprétera certains caractères, faussant l'appel, soit provoquera une exception d'analyse du code :
[code:1]
rem Appel de PS au sein d'un fichier batch
\"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe\" -NoProfile -Command \"&{Import-Module FaitQQChose; Initialize-MonTraitement %Args%}\"
[/code:1]
Dans cet exemple l'expansion de %Args% peut contenir des caractères dollar($) ou une suite de mots similaire à la déclaration d'un paramètre PowerShell ' -fauxparamètre '

Pour contourner ce problème, on est obligé d'utiliser un batch intermédiaire :

REM Fichier batch appelé par un programme externe
rem Récupère tous les paramètres émit par l'appelant
set Args=%*

\"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe\" -NoProfile -Command \"&{Import-Module FaitQQChose; Initialize-MonTraitement Args}\"
rem if %ERRORLEVEL% EQU 1 echo \"Erreur d'appel Powershell\" >> \"%LogFile%\"

La solution ici est de récupèrer l'intégralité de la ligne de commande en renseignant une variable d'environnement. Ensuite dans l'appel à Powershell on passe le nom de la variable d'environnement à une fonction de parsing (on récupère une string).

Le code PS n'a plus qu'a référencer le provider Environment :
[code:1]
#Fonction Powershell de parsing de la ligne de commande
Function Initialize-MonTraitement {
param(
[ValidateNotNullOrEmpty()]
[string] $EnvironmentVariableName
)
#Récupère les informations à partir
#d'une variable d'environnement créée par l'appelant

if (-not (Test-Path Env:$EnvironmentVariableName))
{Throw \"La variable d'environnement $EnvironmentVariableName n'existe pas.\"}
$RegExCmdline='^(?<Param1>.*?) (?<Param2>.*)$' #A adapter
if ((Get-Item Env:$EnvironmentVariableName).Value -match $RegExCmdline)
{
#Récupère les paramètres dans $matches.Param1 ...
}
else
{Throw \"Le parsing de la variable d'environnement $EnvironmentVariableName a échoué.\"}
} #Initialize-MonTraitement
[/code:1]
Ceci fonctionne car le batch(cmd.exe) est le parent du process Powershell et lui 'passe' donc, lors de sa création, son environnement, où l'on retrouve notre variable.

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 ans 6 mois #12823 par Laurent Dardenne
La v3 facilite ces cas:
Easier Reuse of Command Lines From Cmd.exe

The web is full of command lines written for Cmd.exe. These commands lines work often enough in PowerShell, but when they include certain characters, e.g. a semicolon ( ; ) a dollar sign ( $ ), or curly braces, you have to make some changes, probably adding some quotes. This seemed to be the source of many minor headaches.

To help address this scenario, we added a new way to “escape” the parsing of command lines. If you use a magic parameter --%, we stop our normal parsing of your command line and switch to something much simpler. We don’t match quotes. We don’t stop at semicolon. We don’t expand PowerShell variables. We do expand environment variables if you use Cmd.exe syntax (e.g. %TEMP%). Other than that, the arguments up to the end of the line (or pipe, if you are piping) are passed as is.

Here is an example:

[code:1]PS> echoargs.exe --% %USERNAME%,this=$something{weird}
Arg 0 is &lt;jason,this=$something{weird}&gt;[/code:1]<br><br>Message édité par: Laurent Dardenne, à: 4/10/12 15:14

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 ans 6 mois #12860 par jojo
Laurent Dardenne écrit:

Easier Reuse of Command Lines From Cmd.exe

The web is full of command lines written for Cmd.exe. These commands lines work often enough in PowerShell, but when they include certain characters, e.g. a semicolon ( ; ) a dollar sign ( $ ), or curly braces, you have to make some changes, probably adding some quotes. This seemed to be the source of many minor headaches.

To help address this scenario, we added a new way to “escape” the parsing of command lines. If you use a magic parameter --%, we stop our normal parsing of your command line and switch to something much simpler. We don’t match quotes. We don’t stop at semicolon. We don’t expand PowerShell variables. We do expand environment variables if you use Cmd.exe syntax (e.g. %TEMP%). Other than that, the arguments up to the end of the line (or pipe, if you are piping) are passed as is.
Here is an example:


ah l'anglais :evil: mon ennemi eternel :P


Laurent Dardenne écrit:

[code:1]PS&gt; echoargs.exe --% %USERNAME%,this=$something{weird}
Arg 0 is &lt;jason,this=$something{weird}&gt;[/code:1]


c'est génial,

simple question, est ce que ce nouveau mechanisme est géré par le nouveau tabexpansion ou il est gérer par l'interpréteur...

je n'ai pas encore la V3 :(

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 ans 6 mois #12863 par Laurent Dardenne
jojo écrit:

simple question, est ce que ce nouveau mechanisme est géré par le nouveau tabexpansion ou il est gérer par l'interpréteur...

C'est le parseur qui arrête l'analyse dés qu'il rencontre le token --%
Ce qui fait qu'il crée le process sans interpréter les paramètre.
Dans la même veine, plus besoin d'utiliser l'opérateur &amp; pour lancer un exécutable.
jojo écrit:

je n'ai pas encore la V3 :(

Recherche sur le forum 'Version Portable', c'est un bon début, mais il te faut le framework dotnet 4.0.

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.070 secondes
Propulsé par Kunena