ProcessBuilder for .NET Core - c#

In Java I have code:
ProcessBuilder builder = new ProcessBuilder(fileName, license, session, server, db, user, pass, port);
Process process = builder.start();
And in .NET Core I tried this:
String builder = license + " " + session + " " + server + " " + db + " " + user + " " + pass + " " + port;
Precess process = new Process();
process.Start(fileName, builder);
And the version with ProcessStartInfo:
ProcessStartInfo psi = new ProcessStartInfo();
psi.Arguments = builder;
but it does not work. I have error:
Member 'Process.Start(string, string)' cannot be accessed with an instance reference; qualify it with a type name instead
How in .NET Core should I do it?

Use
var process = Process.Start(fileName, builder);
As the error message tells you, Start is a static method and you cannot call static methods on class instances (you can in Java, but that's still a warning).
Also note that you may have to manually quote arguments containing spaces, which Java would have done for you, cf. the example here.

Related

Keeping Escape Characters in C#

I may be completely doing this wrong, or overlooking something obvious but here it goes. I am working with AWS CLI via C#. I am trying to send a command to the command line to change the instance type of the EC2
I've tried different ways of handling this, starting the string with #, single quotes encapsulating double quotes, etc. Here is what I currently have:
private static void resizeCurrentInstance(string instance)
{
string commands = "/C aws ec2 describe-instances --instance-ids " + instance;
string response = getNewProcess(commands);
JObject convertedResponse = JObject.Parse(response);
int i = 0;
string ReturnString = "";
foreach (JObject item in convertedResponse["Reservations"])
{
if (item["Instances"][i]["InstanceType"].Value<string>().Contains(".large"))
{
string sizeUpCommand = "/C aws ec2 modify-instance-attribute --instance-id" + instance + " --instance-type \"{\"Value\": \"m4.4xlarge\"}\"";
string sizeUpResponse = getNewProcess(sizeUpCommand);
Console.WriteLine("Instance Size inscrease " + sizeUpResponse.ToString());
}
else
{
string sizeDownCommand = "/C aws ec2 modify-instance-attribute --instance-id " + instance + ' --instance-type \"{\"Value\": \"m4.large\"}\"';
string sizeDownResponse = getNewProcess(sizeDownCommand);
Console.WriteLine("Instance Size decrease " + sizeDownResponse.ToString());
}
}
}
The problem comes from trying to generate the command string to send to the command line here
string sizeUpCommand = "/C aws ec2 modify-instance-attribute --instance-id" + instance + " --instance-type \"{\"Value\": \"m4.4xlarge\"}\""
This is the command as its give in the amazon docs:
aws ec2 modify-instance-attribute --instance-id i-1234567890abcdef0 --instance-type "{\"Value\": \"m1.small\"}"
I'm trying to figure out how to write a string so the Output is: "{\"Value\": \"m1.small\"}"
If you need to keep a backslash in the string, then you use \\ before the \".
But you are also missing a space after --instance-id, which would mess up the command.
So it should look something like this:
string sizeUpCommand = "/C aws ec2 modify-instance-attribute --instance-id " + instance + " --instance-type \"{\\\"Value\\\": \\\"m4.4xlarge\\\"}\""
If that doesn't work, then output sizeUpCommand to the console and inspect it to make sure it is what it should be.
Try this:
"{\\\"Value\\\": \\\"m1.small\\\"}"

Postman - how to pass data from List<string>, in memory, into -data portion of Newman command line

I need to execute Postman collection from within my C# method.
But instead of the data file, I need to pass the data directly from the method output (as List).
Here is my code:
public StringBuilder RunPostmanCall(string collectionPath, string executionFolder, string environmentPath, List<string> inputFilePath = null)
{
StringBuilder runOutputBuilder = new StringBuilder();
string runOutput = null;
ProcessStartInfo psiNpm = new ProcessStartInfo
{
FileName = "cmd",
RedirectStandardOutput = true,
RedirectStandardInput = true,
UseShellExecute = false
};
Process pNpmRun = Process.Start(psiNpm);
pNpmRun.OutputDataReceived += (sender, a) => runOutputBuilder.AppendLine(a.Data);
Console.WriteLine(" - Install Newman ...");
pNpmRun.StandardInput.WriteLine($"npm install -g newman");
Console.WriteLine(" - Execute Postman Script ...");
string value = $"newman run " +
$"\"" + collectionPath + "\" " +
$"--folder \"" + executionFolder + "\" " +
$"--environment \"" + environmentPath + "\" " +
$"-d \"" + inputFilePath + "\" " +
$"--disable-unicode";
pNpmRun.StandardInput.WriteLine(value);
pNpmRun.BeginOutputReadLine();
pNpmRun.StandardInput.WriteLine("exit 0");
I'm getting the following error:
bin\Debug>newman run "../../api/postman_audit.json" --folder "SearchIndex" --environment "../../api/postman_environment.json" -d "System.Collections.Generic.List`1[System.String]" --disable-unicode
I could save the output into the file, and then just use that file location in the command-line. But I would like to avoid creating a file, and read data directly from the memory.
unfortunately with -d you can only refer to a file in your filesystem.
If you are not willing to write this data directly into a file, i would suggest to set the values directly as a global variable from commandline.
Try to add this parameter to your newman run command
--global-var key=value
You can add your data into a string and add it as a global variable. You can parse it in your pre-request or test-script normally.

Java (Minecraft) doesnt start from c#

When I copy paste the javaw.exe -arguments to console it works but, when I launch it like this it doesn't work.
string directory = "C:\\Users\\Can\\AppData\\Roaming\\.minecraft";
string java = #"C:\windows\system32\javaw.exe";
string javaLocation = "C:\\Program Files\\Java\\jre7\\bin\\javaw.exe";
string RAM = "1G";
string username = "namehere";
string token = "--session token:"+tokenGenerated;
string version = "1.6.2";
string launch = "-Xmx" + RAM + " -Djava.library.path={0}\\versions\\1.6.2\\1.6.2-natives-7453523379463 -cp {0}\\libraries\\net\\sf\\jopt-simple\\jopt-simple\\4.5\\jopt-simple-4.5.jar;{0}\\libraries\\com\\paulscode\\codecjorbis\\20101023\\codecjorbis-20101023.jar;{0}\\libraries\\com\\paulscode\\codecwav\\20101023\\codecwav-20101023.jar;{0}\\libraries\\com\\paulscode\\libraryjavasound\\20101123\\libraryjavasound-20101123.jar;{0}\\libraries\\com\\paulscode\\librarylwjglopenal\\20100824\\librarylwjglopenal-20100824.jar;{0}\\libraries\\com\\paulscode\\soundsystem\\20120107\\soundsystem-20120107.jar;{0}\\libraries\\argo\\argo\\2.25_fixed\\argo-2.25_fixed.jar;{0}\\libraries\\org\\bouncycastle\\bcprov-jdk15on\\1.47\\bcprov-jdk15on-1.47.jar;{0}\\libraries\\com\\google\\guava\\guava\\14.0\\guava-14.0.jar;{0}\\libraries\\org\\apache\\commons\\commons-lang3\\3.1\\commons-lang3-3.1.jar;{0}\\libraries\\commons-io\\commons-io\\2.4\\commons-io-2.4.jar;{0}\\libraries\\net\\java\\jinput\\jinput\\2.0.5\\jinput-2.0.5.jar;{0}\\libraries\\net\\java\\jutils\\jutils\\1.0.0\\jutils-1.0.0.jar;{0}\\libraries\\com\\google\\code\\gson\\gson\\2.2.2\\gson-2.2.2.jar;{0}\\libraries\\org\\lwjgl\\lwjgl\\lwjgl\\2.9.0\\lwjgl-2.9.0.jar;{0}\\libraries\\org\\lwjgl\\lwjgl\\lwjgl_util\\2.9.0\\lwjgl_util-2.9.0.jar;{0}\\versions\\1.6.2\\1.6.2.jar net.minecraft.client.main.Main --username " + username + " " + token + " --version " + version + " --gameDir {0} --assetsDir {0}\\assets";
launch = String.Format(launch, directory);
string text = launch;
// WriteAllText creates a file, writes the specified string to the file,
// and then closes the file.
Directory.SetCurrentDirectory(#"C:\windows\system32\");
Process.Start("javaw.exe",
Path.Combine(launch));
What am I doing wrong?
Why do you need to call Path.Combine if your whole path is in one string?
Assuming your javaw.exe is actually in C:\windows\system32\, Process.Start("java.exe", launch); should work as intended.
Source - Path on MSDN: http://msdn.microsoft.com/en-us/library/system.io.path.aspx
Just use Java's real location instead of "javaw" like "c:\programfiles\Java\jre7\bin\javaw.exe"

C# command-line argument with newline fails in C# but not in python. Need to make the c# work

Env: .NET 3.5 Visual Studio 2008 SP1, on Win XP SP3, Python 2.7. Corporate image, no admin rights.
In C# 3.5, I want to pass a parameter to a command-line program, and this parameter contains newlines. It works in Python 2.7 but not in C#.
When body contains newline, c# truncates the result, but python passes it correctly.
Python code
cmd = self.app_path + ' email -Subject "' + subject + '" -From "' + address_from + '" -To "' + address_to +'" -Body "' + body +'"'
cmd_result = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()
C# code:
string Command = "<path to executable>";
string arguments = " email -From " + FromAddress + " -To " + ToAddress + " -Subject \"" + SubjectLine + "\" -Body \"" + emailBody + "\" ";
System.Diagnostics.ProcessStartInfo start = new System.Diagnostics.ProcessStartInfo(Command, arguments);
start.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
start.CreateNoWindow = false;
start.UseShellExecute = true;
System.Diagnostics.Process process = System.Diagnostics.Process.Start(start);
Any idea?
Update: body in the python example and emailBody in the c# example contain the same string, as strings are represented in each language.
Update: noticed the command wasn't terminated correctly in the python code. I added + '"' at the end of line 2. The code ran as before.
Also, as you can tell, the app called sends the body (emailBody) parameter content as an email body.
Sorry but I think it is the process you call that does not take the arguments correctly; it is not the C# that is involved, and as a proof of that:
Create a new windows form application
Make sure that the Main signature looks like this:
static void Main(string[] args)
Make sure that the call of your Main Form (named Form1) looks like this:
if (args==null)
{
Application.Run(new Form1());
}
else
{
Application.Run(new Form1(args));
}
Add a textbox to your form, with the multiline property set to true
Add a button to your form
Run the application once
Then Put this in the code of your button1_Click function (replace TheNameOfTheCurrentApp):
string Command = "TheNameOfTheCurrentApp";
string arguments = textBox1.Text;
System.Diagnostics.ProcessStartInfo start = new System.Diagnostics.ProcessStartInfo(Command, arguments);
start.WindowStyle = System.Diagnostics.ProcessWindowStyle.Maximized;
start.CreateNoWindow = true;
start.UseShellExecute = true;
System.Diagnostics.Process process = System.Diagnostics.Process.Start(start);
Add this constructor to your form:
public Form1(string[] args)
{
InitializeComponent();
textBox1.Text = string.Join(" ", args);
}
Then run your app, insert muliple lines in your textbox and click the button. The same app will appear with the textbox correctly filled with the line breaks

Creating SQL Server backup file (.bak) with c# to any location

I'm trying to write simple application in C# which will allow me to backup, zip and send over ftp my SQL Server database.
One problem I have encountered is that I'm not able to create the backup file (.bak) if I try to do it in different location than "C:\Program Files\Microsoft SQL Server\MSSQL.3\MSSQL\Backup" or "C:\Program Files\Microsoft SQL Server\MSSQL.3\MSSQL\Data" folder. I understand that this is a premission problem. Could someone point me to the resources or write here a short snippet how to programmatically add such a permission to any folder on my system.
Regards
Kris
i assume you are running your programm as a scheduled task ... did you give writing permissions to the target folder for the executing user of the task??
edit:
with permissions you can have 2 scenarios:
windows authenification
mixed authentification
if you are using windows authentification, the read and write permissions of the windows user are taken. otherwise the permissions for the sql server service account.
and this behaviour makes sense to me and maybe hits the nail in your scenario!
edit 2:
i don't want to encourage you to do so ... some admins may hate you when you mess up their acl's
but this may do the trick
btw: Magnus Johansson already gave you a "try-this" link
no matter for which method you go - be sure to hand in the correct user (as descriped above!)
(for full history)
...
side-note:
i know this is not the exact answer to your question, but i would recommend you smo to generate backups ...
like
using Microsoft.SqlServer.Management.Smo;
var bdi = new BackupDeviceItem(/* your path inlcuding desired file */);
var backup = new Backup
{
Database = /* name of the database */,
Initialize = true
};
backup.Devices.Add(bdi);
var server = new Server(this.SqlServer);
try
{
backup.SqlBackup(server);
}
catch (Exception ex)
{
// * log or sth
}
you only have to care for the .dll's. take assemblies for the desired server version (some params/properties vary through different server versions)
more info here
Ok Guys, Magnus and dittodhole! Thanks a lot for your help. I have combined Magnus'es link to the article on setting up permisions on the folder together with some more research and finally I've got it :).
So reassuming, I'm using Smo, and to create a folder with proper permissions I have to look for the group instead of win32_Users. Here you go a short snippet if someone finds this post he can find it usefull:
string tempPath = Directory.CreateDirectory("C:\\path_to_your_folder").FullName;
//set permissions
SelectQuery sQuery = new SelectQuery("Win32_Group",
"Domain='" +
System.Environment.UserDomainName.ToString() +
"'");
try
{
DirectoryInfo myDirectoryInfo = new DirectoryInfo("C:\\path_to_your_folder");
DirectorySecurity myDirectorySecurity = myDirectoryInfo.GetAccessControl();
ManagementObjectSearcher mSearcher = new ManagementObjectSearcher(sQuery);
foreach (ManagementObject mObject in mSearcher.Get())
{
string User = System.Environment.UserDomainName + "\\" + mObject["Name"];
if(User.StartsWith("your-machine-name\\SQL"))
{
myDirectorySecurity.
AddAccessRule(new FileSystemAccessRule(User,
FileSystemRights.FullControl,
AccessControlType.Allow));
}
}
myDirectoryInfo.SetAccessControl(myDirectorySecurity);
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
Again thanks everyone for your help! Stackoverflow rocks!
Here is a procedure is use for back up in C#.Hope it helps
public void BackupDatabase (string BackUpLocation, string BackUpFileName, string
DatabaseName, string ServerName )
{
DatabaseName = "[" + DatabaseName + "]";
string fileUNQ = DateTime.Now.Day.ToString() + "_" + DateTime.Now.Month.ToString() + "_" + DateTime.Now.Year.ToString() +"_"+ DateTime.Now.Hour.ToString()+ DateTime.Now .Minute .ToString () + "_" + DateTime .Now .Second .ToString () ;
BackUpFileName = BackUpFileName + fileUNQ + ".bak";
string SQLBackUp = #"BACKUP DATABASE " + DatabaseName + " TO DISK = N'" + BackUpLocation + #"\" + BackUpFileName + #"'";
string svr = "Server=" + ServerName + ";Database=master;Integrated Security=True";
SqlConnection cnBk = new SqlConnection(svr);
SqlCommand cmdBkUp = new SqlCommand(SQLBackUp, cnBk);
try
{
cnBk.Open();
cmdBkUp.ExecuteNonQuery();
Label1.Text = "Done";
Label2.Text = SQLBackUp + " ######## Server name " + ServerName + " Database " + DatabaseName + " successfully backed up to " + BackUpLocation + #"\" + BackUpFileName + "\n Back Up Date : " + DateTime.Now.ToString();
}
catch (Exception ex)
{
Label1.Text = ex.ToString();
Label2.Text = SQLBackUp + " ######## Server name " + ServerName + " Database " + DatabaseName + " successfully backed up to " + BackUpLocation + #"\" + BackUpFileName + "\n Back Up Date : " + DateTime.Now.ToString();
}
finally
{
if (cnBk.State == ConnectionState.Open)
{
cnBk .Close();
}
}
}
Take a look at this article.
Remember to set the permissions for the account that the SQL Server instance is running with.
Although this may not answer your immediate question, I'd advice you to look into SQL Server Integration Services (SSIS). This looks like the exact thing SSIS was created for, and in the 2008 version there's the possibility to use C# code if needed, should the standard components not do what you need (earlier versions used VB.NET).
MSDN SSIS Info Link 1
SSIS 2005 Tutorial Link 2
Take a look at it.

Categories

Resources