C# run Powershell script async - c#

I'm trying to run a powershell script using the following method:
> PowerShellInstance.AddScript(
> #"write-output balls;Start-Sleep -s 2;write-output balls;Start-Sleep -s 2;write-output balls;Start-Sleep -s 2");
This works fine, however the following does not. Any ideas?
PowerShellInstance.AddScript(
#"c:\folder\script.ps1");

This is why...
PowerShellInstance.AddScript(
#"& ""c:\folder\script.ps1""");

Related

Run PS Script with arguments

I'm trying to run powershell script from relative path (script is placed in project folder) with arguments.
This is what i tried:
public static void RunPSScriptWithArgumentsFromScriptsFolder(string NameOfScriptFile, string arguments)
{
string RelativePathToApp = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
Process proc = Process.Start("C:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe ", #"-noexit -File """+RelativePathToApp+"\\Scripts\"" +NameOfScriptFile +arguments);
proc.WaitForExit();
}
Problem is when i run it my powershell window just flash once and disseapers even with -noexit switch.
This is script which im trying to run for better reproducing problem:
https://community.spiceworks.com/scripts/show/4378-windows-10-decrapifier-18xx-19xx
Any ideas what could be wrong?
PS: My Set-ExecutionPolicy is set to Unrestricted

Let the shell parse or do your own parsing (powershell/cmd)

I develop an application with command line parameters and use it in cmd shell and powershell. There it is obvious that the arguments are received differently in main() of my application.
static void Main(string[] args)
{
// In cmd shell: args[0] == "-ipaddress=127.0.0.1"
// In powershell: args[0] == "-ipaddress=127"
// and args[1] == ".0.0.1"
}
Example:
myApp.exe -ipaddress=127.0.0.1
In my C# application the arguments are interpreted differently depending on the shell I start the app in.
In cmd shell: arg[0]=-ipaddress=127.0.0.1
In powershell: arg[0]=-ipaddress=127 and arg[1]=.0.0.1
What is best practice here?
Should I join all args[] and parse the arguments in my application?
Should I rely on the shell's parser?
I would abandon cmd shell support completely and just created proper PowerShell cmdlet. Writing a Windows PowerShell Cmdlet. But I don't know your exact requirements.
In general calling executable from cmd and PowerShell should work same way. For example line, "> ping -n 3 google.com" just works fine no matter where you put it.
tl;dr:
When calling from PowerShell, enclose the entire argument in '...' (single quotes) to ensure that it is passed as-is:
myApp.exe '-ipaddress=127.0.0.1'
You've run into a parsing bug[1]
where PowerShell breaks an unquoted argument that starts with - in two at the first .
The following simplified example demonstrates that:
# Helper function that echoes all arguments.
function Out-Argument { $i = 0; $Args | % { 'arg[{0}]: {1}' -f ($i++), $_ }}
# Pass an unquoted argument that starts with "-" and has an embedded "."
Out-Argument -foo=bar.baz
The above yields:
arg[0]: -foo=bar
arg[1]: .baz
[1] The presumptive bug is present as of Windows PowerShell v5.1 / PowerShell Core v6.0.1 and has been reported on GitHub.
A PSv2 variation of the bug affects . when enclosed in "..." in the interior of the argument - see this answer of mine.

Handling Jenkins Groovy script exceptions

I am executing a C# exe, CRS.exe, that I expect to return a non-zero value, such as -1. I am using ps to get the value back, and have this within a stage:
try{
pcode = (powershell(returnStdout: true, script: 'return Invoke-Expression -Command \" .\\perfmon\\CRS.exe hello \"'))''
echo "Pcode = ${pcode} "
}
catch (err) {echo err.message }
echo "Pcode = ${pcode} "
Based on this post, "Normally, a script which exits with a nonzero status code will cause the step to fail with an exception." --
Jenkins pipeline bubble up the shell exit code to fail the stage
I want to handle this non-zero result, is the exception handler the only way?
Results of above run:
Running PowerShell script
tester arg = hello
[Pipeline] echo
script returned exit code -1
[Pipeline] echo
Pcode = null
Interestingly enough, a char return seems to be fine? This returns without throwing an exception
icode = (powershell(returnStdout: true, script: 'return Invoke-Expression -Command \'.\\perfmon\\zipInstaller.ps1 -urlString ' + fileContents + "'"))
echo "icode = ${icode} "
Results in
[Pipeline] {
[Pipeline] powershell
[Chris] Running PowerShell script
[Pipeline] echo
icode = -5
I would like to catch the return codes from the exe's and manage my groovy pipelines flow based on that. Any insight would be greatly appreciated.
Instead of using returnStdout: true, try using returnStatus: true. It should always return the exit code. Not as helpful if you need the output from the powershell command all at once (without returnStdout, it will just print output to the Jenkins log), but as a workaround for that you could pipe output to a file and then print that out.
Another option (but it's ugly, so I don't recommend it) is to call Powershell from a bat command. bat should mask the error code for the powershell command, so Jenkins won't get excited and fail automatically, and you'll still get stdout. Obviously not too helpful if you actually wanted the error code though. Your line would look something like
pcode = (bat(returnStdout: true, script: 'Powershell.exe "return Invoke-Expression -Command \" .\\perfmon\\CRS.exe hello \"'"))
That line will need a bit of refining, but it might be another option.

WPF app runs on command line

I have a WPF app. I want to use the same app in command line also. I did the following if args.Length > 0
AttachConsole(-1);
Console.WriteLine("Start");
Console.WriteLine("Stop");
FreeConsole();
It give me o/p like that
C:\Work>TestWriteCLI.exe -h
C:\Work>Start
Stop
The problem is that it does not returns to next command prompt until i press and Enter.
I tried AllocConsole() ebut it create a new console which i don't want. I want the o/p should
be like this:
C:\Work>TestWriteCLI.exe -h
Start
Stop
C:\Work>

Having some trouble executing "svn log" with Process.Start() in LINQPad

Process.Start("svn.exe", "log c:\\work\\lidac\\v1\\ -r {2014-09-01}:{2014-09-24} --xml > c:\\work\\commits.xml");
SVN is throwing an error over the >
Error resolving case of >
I am not sure why. The same command works if I type it directly into the command prompt. Any ideas?
You are passing that redirect output symbol to the svn.exe process. He doesn't understand what > c:\work\commits.xml means. If you want to do the redirect output to a file, you can either write code to get the output from the process object, or try something like:
Process.Start("cmd.exe", #"/C svn log C:\work\lidac\v1\ -r {2014-09-01}:{2014-09-24} --xml > c:\work\commits.xml");

Categories

Resources