I have a C# application calling a bat file:
new string[] { branchName + ".Order", "Order.bak", "Order"}
var arguments = String.Format("\"{0}\"\"{1}\"\"{2}\"\"{3}\"", stringse[0], stringse[1], stringse[2], sqlPath + "\\");
var psi = new System.Diagnostics.ProcessStartInfo(filename)
{
RedirectStandardOutput = true,
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
UseShellExecute = false,
Arguments = arguments
};
Process createDBs = Process.Start(psi);
System.IO.StreamReader myOutput = createDBs.StandardOutput;
while (!createDBs.HasExited)
{
string output = myOutput.ReadToEnd();
LogStep(output);
}
The bat file looks like this:
#echo off
REM ************************************************
REM * RestoreDB script for use by Development Team *
REM ************************************************
#echo %1 %2 %3 %4
#echo Restore of database started...
SQLCMD -S (local) -d Master -i RestoreDB.sql -v varDatabaseName=%1 varDatabaseBackupFileName= %2 varLogicalName= %3 varSQLDataFolder= %4
#echo Restore of database finished...
pause
The Sql script looks receive these parameters like this:
SET #DatabaseName = N'$(varDatabaseName)'
SET #DatabaseBackupFileName = N'$(varDatabaseBackupFileName)'
SET #LogicalName = N'$(varLogicalName)'
SET #SQLDataFolder = N'$(varSQLDataFolder)'
(Can't paste complete code due to security reasons)
Now my problem is that I don't think I'm passing the variables from bat to sql script correctly.
When calling the bat file out of C# it echo's the values
When calling the sql directly out of command prompt it works correctly, so I know my sql script is working:
SQLCMD -S (local) -d Master -i RestoreDB.sql -v varDatabaseName="Piet.Order.Test" varDatabaseBackupFileName="Order.bak" varLogicalName="Order" varSQLDataFolder="C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\"
I don't get any errors back to my C# application, so when running my application it just runs and calls the bat with parameters, the call from bat to sql seems to go wrong.Is it a format problem with my parameters. I tried single quotes '%1' and tried doubele quotes "%1", nothing seems to work.Can anybody shine some light.Any way maybe how I can retrieve the error that is happening with the call to sql
You need to add a space between arguments
var arguments = String.Format("\"{0}\" \"{1}\" \"{2}\" \"{3}\"",
stringse[0], stringse[1], stringse[2], sqlPath + "\\");
In these scenarios (debugging parameters) could be very useful to start the command processor and leave the console window open after the execution of the program
var arguments = String.Format("/K {4} \"{0}\" \"{1}\" \"{2}\" \"{3}\"",
stringse[0], stringse[1], stringse[2], sqlPath + "\\", filename);
and call the command processor in the ProcessStartInfo
var psi = new System.Diagnostics.ProcessStartInfo("cmd.exe")
Related
Executing by C# a complicated batch file, that setting session variables example
SET TEST = rainbow
getting the famous
A duplicate file name exists, or the file cannot be found.
I used
string args = string.Format("/k \"cd /d {0} && {1}\"", s.Path, s.Filename + " " + userChoice);
RunBatch("cmd.exe", args, s.Path);
.
.
ProcessStartInfo startInfo = new ProcessStartInfo()
{
UseShellExecute = false,
WorkingDirectory = workingDir,
FileName = cmd,
Arguments = cmdArgs
};
Process.Start(startInfo);
when trying it on simple batch file working. With the complex one getting the error mention above.
--
I tried also to write by C#, a new batch file that has on the first line the
setlocal enableextensions disabledelayedexpansion
, then calling the needed one, and execute this batch by C#, the error again is the same...
any tip?
I am trying to execute one command through process but it is throwing exception as "The system cannot find the file specified". When i run this command directly on command prompt. It is working fine.
Command: start cmd.exe #cmd /k "NTttcpr.exe -r -m 1,*,192.168.1.2 -a 2 -t 120 -wu 10 -cd 10 >> NTTTCP-1T-TCP-IPV4-Rx-MTU1500-Support-port-1-Rx-AMD-10-GBE-RJ45-ITR-1.log"
This command executes perfectly if i run on command prompt.
This is how i written code:
string tool = #"NTttcpr.exe";
string command = " -r -m 1,*,192.168.1.2 -a 2 -t 120 -wu 10 -cd 10 >> NTTTCP-1T-TCP-IPV4-Rx-MTU1500-Support-port-1-Rx-AMD-10-GBE-RJ45-ITR-1.log";
private void RunCommand(string tool, string command)
{
try
{
logger.Info($"{MethodBase.GetCurrentMethod()}: {tool} {command}");
Process pro = new Process();
pro.StartInfo.FileName = "start cmd ";
pro.StartInfo.Arguments = "#cmd /k " + '"' + tool + " " + command + '"';
pro.StartInfo.UseShellExecute = false;
pro.StartInfo.RedirectStandardOutput = true;
logger.Info($"{MethodBase.GetCurrentMethod()}: Executing command: {tool} {command}");
pro.StartInfo.Verb = "runas";
pro.Start();
//pro.WaitForExit(MillisecondsTimeout);
//Thread.Sleep(MillisecondsTimeout);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
logger.Error($"{MethodBase.GetCurrentMethod()}: Exception occurred while uni-directional command!!");
logger.Error($"{MethodBase.GetCurrentMethod()}: {ex}");
}
}
Note:
NTttcpr.exe file is already present in current executing directory.
Please help me to solve this.
This should be because you have not set the working directory, add pro.StartInfo.WorkingDirectory = "path to NTttcpr.exe" do not add NTttcpr.exe, just add the location.
Let me know if this works.
cmd.exe is not required for Process class. Try like below.
pro.StartInfo.FileName = "NTttcpr.exe";
pro.StartInfo.Arguments = command
It is supposed to be easy, but I can't get it work.
When I run the following command inside cmd, it works perfectly fine. When I run the command inside the c# code, it won't do anything (no exception has been thrown either).
Here is the command I'm using (which works perfectly fine when using directly on cmd.exe):
cd %ProgramFiles%\PostgreSQL\12\bin && SET PGPASSWORD=mypassword&& pg_restore.exe -U username -d dbname C:\file\to\dump\my.dump
Here is what I'm trying to do in c# (not working):
var arg = #"cd %ProgramFiles%\PostgreSQL\12\bin && SET PGPASSWORD=mypassword&& pg_restore.exe -U username -d dbname C:\file\to\dump\my.dump";
Process.Start("cmd.exe", arg);
Am I missing something? I found a lot of posts concerning c# starting a process, but nothing solved my problem. I also tried to start the process with StartInfo and added the Properties like Arguments, FileName, etc., but it did not work either.
Be aware, the question process.start() arguments is not the same - in my case, I neet to set the system variable (SET PGPASSWORD), since pg_restore has no password argument.
cmd is just the console, it isn't needed to start another process.
The application you want to run is pg_restore.exe in the %ProgramFiles%\PostgreSQL\12\bin folder. You can pass environment variables through ProcessStartInfo.EnvironmentVariables dictionary. I'm not sure if the ProcessStartInfo constructor expands environment variables. You can use Environment.ExpandEnvironmentVariables to ensure the path is correct :
var binFolder=#"%ProgramFiles%\PostgreSQL\12\bin\";
var fullPath=Path.Combine(binFolder,"pg_restore.exe");
var arguments=#"-U username -d dbname C:\file\to\dump\my.dump";
var fullPath=Environment.ExpandEnvironmentVariables(pathToRestore);
var startInfo=new ProcessStartInfo(fullPath,arguments) {
UseShellExecute =false,
//Need this to read the output if needed
RedirectStandardOutput = true;
//Set if needed
WorkingDirectory = binFolder
};
startInfo.EnvironmentVariables["PGPASSWORD"]=password;
var process=Process.Start(startInfo);
Console.WriteLine(process.StandardOutput.ReadToEnd());
You need to prefix your argument string with /c so that cmd knows that you're telling it what to do:
var arg = #"/c cd %ProgramFiles%\PostgreSQL\12\bin && SET PGPASSWORD=mypassword&& pg_restore.exe -U username -d dbname C:\file\to\dump\my.dump";
Process.Start("cmd.exe", arg);
Try this:
var command = "SET PGPASSWORD=mypassword && pg_restore.exe";
var param = "-U username -d dbname C:\file\to\dump\my.dump";
var process = new Process();
var processInfo = new ProcessStartInfo(command, param)
{
WorkingDirectory = #"%ProgramFiles%\PostgreSQL\12\bin"
};
process.StartInfo = processInfo;
process.WaitForExit();
I want cmd command in my c# winforms program. I want use command to compress file with 7zip.
In normal cmd i use cd "C:\Program Files(x86)\7-Zip" & 7z.exe a -tzip "C:\xyz\test\txt" "C:\xyz\test\txt" -m0=BZip2 -mx5
string zip = #"/c C:\Program Files(x86)\7-Zip";
string file = #"/c C:\xyz\txt";
string conv = "/c & 7z.exe a -tzip";
string method = "/c -m0=BZip2 -mx5";
System.Diagnostics.ProcessStartInfo proc = new System.Diagnostics.ProcessStartInfo();
proc.FileName = #"C:\windows\system32\cmd.exe";
proc.Arguments = #"/c cd" + zip + conv + file + file + method;
System.Diagnostics.Process.Start(proc);
Doesn't work my code. How can i use this command in my program. I want compress file when i click in button
Something like this:
// File (exe) to start: combination of folder and exe
string fileName = Path.Combine(
// Let's not hardcode "C:\Program Files(x86)" and alike
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),
#"7-Zip",
#"7z.exe");
// If desired arguments are
// a -tzip "C:\xyz\test\txt" "C:\xyz\test\txt" -m0=BZip2 -mx5
// we can join them as
string arguments = string.Join(" ",
#"a",
#"-tzip", //TODO: you may want to have these values
#"""C:\xyz\test\txt""", // as variables like file, conv, method etc.
#"""C:\xyz\test\txt""",
#"-m0=BZip2",
#"-mx5");
ProcessStartInfo procInfo = new ProcessStartInfo() {
FileName = fileName, // We want to start fileName
Arguments = arguments, // With arguments
}
// Process is IDisposable, do not forget to Dispose HProcess handle
using (var process = Process.Start(procInfo)) {
// It's fire and forget implementation, if you want to wait for results
// add process.WaitForExit();
// process.WaitForExit(); // uncomment, if you want to pause
}
You seem to have made a mistake with your arguments.
Your current command line will be:
C:\windows\system32\cmd.exe /c cd/c C:\Program Files(x86)\7-Zip/c & 7z.exe a -tzip/c C:\xyz\txt/c C:\xyz\txt/c -m0=BZip2 -mx5
The spurious /c everywhere is not going to help and neither are the lack of spaces.
I'm guessing what you meant to run was these two commands in succession:
cd C:\Program Files(x86)\7-Zip
7z.exe a -tzip C:\xyz\txt C:\xyz\txt -m0=BZip2 -mx5
Which means you should change your code to:
string zip = #" C:\Program Files(x86)\7-Zip";
string file = #" C:\xyz\txt";
string conv = " & 7z.exe a -tzip";
string method = " -m0=BZip2 -mx5";
This will produce:
C:\windows\system32\cmd.exe /c cd C:\Program Files(x86)\7-Zip & 7z.exe a -tzip C:\xyz\txt C:\xyz\txt -m0=BZip2 -mx5
I am writing C# code to execute a powershell script.
The powershell script has two arguments:
subscriptionId of type string
resourceGroupNames of type string[]
Problem:
When running the C# program, the resourceGroupNames that is passed a is not being read by the powershell script.
Additionally, when running the C# program, powershell prompts me a message "Do you want to run this script?" Is there anyway to suppress this alert and have the powershell script to run automatically?
Here is my code:
Note that chefRepo is the path of the powershell script.
public void DoDeploymentRTM(string chefRepo, string subscriptionId, string[] resourceGroupNames)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #"powershell.exe";
startInfo.Arguments = String.Format(#"& '{0}\AzurePowerShellScripts\azureVMStatusFetch.ps1' -subscriptionId {1} -resourceGroupNames {2}", chefRepo, subscriptionId, resourceGroupNames);
startInfo.Verb = "runas";
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
}
For passing an array as powershell argument you need to separate it's values by commas i.e. for integers you would pass e.g 1,2,3.
For string you need additional quotation marks (in case some items contain space) e.g.'first string','second string','third'.
In C# you would do this by
string.Join(',', resourceGroupNames.Select(x => "'" + x + "'"))
In order to make this approach work when calling by ProcessStartInfo you need to use powershell option -Command so that the array would be parsed correctly (see more details in question).
Concerning your second problem use powershell commandline option -ExecutionPolicy UnRestricted
Finally you just need to change your Arguments like this:
startInfo.Arguments = String.Format("-ExecutionPolicy UnRestricted -Command &\"'{0}\\AzurePowerShellScripts\\azureVMStatusFetch.ps1' - subscriptionId {1} -resourceGroupNames {2}\"", chefRepo, subscriptionId, string.Join(',', resourceGroupNames.Select(x => "'" + x + "'")));
or easier (for C# 7.0 or higher)
startInfo.Arguments = $"-ExecutionPolicy UnRestricted -Command &\"'{chefRepo}\\AzurePowerShellScripts\\azureVMStatusFetch.ps1' - subscriptionId {subscriptionId} -resourceGroupNames {string.Join(',', resourceGroupNames.Select(x => $"'{x}'"))}\"";