Install SQL Server 2012 Express Programmatically - c#

I work on Setup application to install all requirement for my WPF product, one of the requirement is SQL Server 2012 Express, the code below is to install it after I generate the configuration file for silent installation :
private void SetupSQLServer()
{
string result = "";
string commandLine = "";
if (os64)
commandLine = string.Format(#"{0}\SQLServer\sql64\setup.exe PCUSOURCE={0}\SQLServer\sql64 /SAPWD=""p#ssw0rd"" /CONFIGURATIONFILE={0}\SQLServer\ConfigurationFile64.ini /HIDECONSOLE", setupFolder);
else
commandLine = string.Format(#"{0}\SQLServer\sql86\setup.exe PCUSOURCE={0}\SQLServer\sql86 /SAPWD=""p#ssw0rd"" /CONFIGURATIONFILE={0}\SQLServer\ConfigurationFile32.ini /HIDECONSOLE", setupFolder);
startInfo.WorkingDirectory = setupFolder;
startInfo.Arguments = "/c " + commandLine;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
try
{
process.Start();
}
catch (Exception e)
{
result = e.Message;
}
result = result + "\n" + process.StandardOutput.ReadToEnd();
UpdateStepResult(result);
}
There's no error in the code but it does not work .. when I run the code the command window appear and disappear and nothing happen.
UPDATE:
When I used:
fileName = string.Format(#"{0}\SQLServer\sql64\setup.exe", setupFolder);
The installation is run but without configuration file, when I used:
fileName = string.Format(#"{0}\SQLServer\sql64\setup.exe /CONFIGURATIONFILE={0}\SQLServer\sql64\ConfigurationFile64.ini", setupFolder);
It gives me this error "The system cannot find the file specified" !!!
The file is exist in the same folder !!
Please can you help me to discover the mistake.
Thanks in advance.

The ProcessStartInfo requires the FileName property to be valid. Your code above doesn't set it but pass everything as Arguments.
Probably you need to separate the command line in two parts. The Executable to run and the arguments to pass
if (os64)
{
fileName = string.Format("{0}\SQLServer\sql64\setup.exe", setupFolder);
commandLine = string.Format(#"PCUSOURCE={0}\SQLServer\sql64 /SAPWD=""p#ssw0rd"" /CONFIGURATIONFILE={0}\SQLServer\ConfigurationFile64.ini /HIDECONSOLE", setupFolder);
}
else
{
// Same for 32 bit
.....
}
....
startInfo.FileName = fileName;
....

Related

How can I run Python script with commands in C# button

This is my codes
ProcessStartInfo ps = new ProcessStartInfo();
ps.FileName = #"C:\\Users\\Admin\\AppData\\Local\\Programs\\Python\\Python37\\python.exe";
ps.WindowStyle = ProcessWindowStyle.Normal;
ps.Arguments = string.Format("C:\\Users\\Admin\\Downloads\\order.py-master\\order.py-master\\order.py -a 999 -b ",this.textbox.Text);
Process.Start(ps);
There is a function that I am using in my project that is called "RunBat" which runs bat files, but can really work on any file extension such as .py as well.
RunFile.RunBat("Directory/To/Script.py", true);
The way this was possible was by using Process.Start() and setting the path into the base directory, so all you would need to do is input the rest of the directory that leads to the file.
public static int RunBat(string currentFile, bool waitexit)
{
try
{
string path = AppDomain.CurrentDomain.BaseDirectory;
Process process = new Process();
process.StartInfo.FileName = path + currentFile;
process.Start();
if (waitexit == true)
{
process.WaitForExit();
}
return 0;
}
catch
{
return 1;
}
}
The bool waitexit is an optional setting to keep the prompt open while it does it's commands. You can turn this off by using false.
If this fails to work, and you are trying to run a file that is NOT added as a resource in the code, then you would want to change the string path = AppDomain.CurrentDomain.BaseDirectory; to C:\\.
What this will do is instead of starting from the base directory of the application, it will start from the C:\ drive, and then you would continue the rest of the directory in currentFile.

"The system cannot find the file specified" error on process.Start();

I am trying to get the process respond as a string so I can use it in different place in my code, this is the solution that I have so far:
const string ex1 = #"C:\Projects\MyProgram.exe ";
const string ex2 = #"C:\Projects\ProgramXmlConfig.xml";
Process process = new Process();
process.StartInfo.WorkingDirectory = #"C:\Projects";
process.StartInfo.FileName = "MyProgram.exe ";
process.StartInfo.Arguments = ex2;
process.StartInfo.Password = new System.Security.SecureString();
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
try
{
process.Start();
StreamReader reader = process.StandardOutput;
string output = reader.ReadToEnd();
}
catch (Exception exception)
{
AddComment(exception.ToString());
}
But when I'm running this I get:
"The system cannot find the file specified" error in process.Start(); without
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
The code runs fine but it just open console window and all the process response is trow there so I can't use it as string.
Does anyone know why I am getting this error or maybe a different solution to my problem?
I suspect the problem is that the filename you're specifying is relative to your working directory, and you're expecting Process.Start to look there when starting the process - I don't believe it works that way when UseShellExecute is false. Try just specifying the absolute filename of the process you want to start:
process.StartInfo.FileName = #"C:\Projects\MyProgram.exe";
Note that I've also removed the space from the end of the string you were assigning for the FileName property - it's entirely possible that was casuing the problem too.
For System32 access if you are trying to RUN an x86 Application on x64 then you must use the "Sysnative" keyword instead of "System32" in your filename.
EG: instead of:
C:\Windows\System32\whoiscl.exe
It should be:
C:\Windows\Sysnative\whoiscl.exe
Hope this helps someone

Retrieve cmd prompt output from PsExec command?

Use case: I am checking certain credentials on a remote system by running commands via PsExec (i.e. for this example, I am trying to retrieve the KB articles currently installed on the remote system).
I have the following to retrieve command output:
public string GetCmDOutput(string cmd)
ProcessStartInfo startInfo = new ProcessStartInfo("control", cmd)
{
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
};
string output = string.Empty;
Process process = Process.Start(startInfo);
process.OutputDataReceived += (sender, e) => output = string.Concat(output, e.Data);
process.BeginOutputReadLine();
process.Start();
process.WaitForExit();
Delay.Milliseconds(1500) //API-specific delay
return output;
}
Whenever I use GetCmdOutput() to run a command locally it works like a charm, but if I try to run a command with PsExec, my output is empty.
For instance, I ran the following:
string cmd = #"\psexec.exe \\remoteComputerName -u username -p password -c cmd /c wmic qfe";
GetCmdOutput(cmd);
Report.Info(cmd); //API-specific reporting
And an empty string was returned.
After playing around with this for a couple of hours, I feel I may need a second set of eyes. What might be causing this issue?
I have run into this same problem. My solution was to run cmd and have it call psexec. I have psexec's output saved to a temp file for further manipulation. My code is returning a List.
public List<string> ExecutePSExec(string hostname)
{
List<string> recordNames = new List<string>();
string command = #"\\path\to\psexec.exe /accepteula \\" + hostname + ". exe-to-run-remotely";
try
{
string location = AppDomain.CurrentDirectory.BaseDirectory;
string cmdWithFileOutput = string.Format("{0} >{1}temp.log", command, location);
procStartInfo.UseShellExecute = true;
procStartInfo.CreateNoWindow = true;
procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
Process proc = new Process();
proc.StartInfo = procStartInfo;
proc.Start();
proc.WaitForExit();
// Read file contents, manipulate data and then delete temp file here
}
catch (Exception e)
{
Console.WriteLine("Failure to run psexec: {0}", e.Message);
}
return recordNames;
}
NOTE: I ran into another problem and found out that running psexec this way requires the remote hostname (not IP Address) in the command to end in a period \\" + hostname + ".
This code assumes you can run psexec on the remote machine as your current user.

Run "tf.exe status" in C# and save the result

I´m trying to create a small console app in c#. I want to run the program and save all pending changes in TFS to a .txt file. But I cant get the arguments to work. Can someone help me?
Here is my code i haved done so far:
string argument = "#tf.exe status /collection:http://tiffany:8080/tfs/ /user:* /format:detailed >c:\\Status\\Detailed.txt";
try
{
Process process = new Process();
process.StartInfo.Arguments = "#call" + " " + "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\Common7\\Tools\\VsDevCmd.bat";
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Verb = "runas";
process.StartInfo.Arguments = argument;
process.StartInfo.CreateNoWindow = false;
process.Start();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.ReadKey();
}
aI'm not really sure that I understand what you're trying to call, exactly.
Let's assume you want to run the following command line from a C# application, as if you would call it from a command line:
tf.exe status /collection:http://tiffany:8080/tfs/ /user:* /format:detailed >c:\\Status\\Detailed.txt"
I would use this code:
string arguments = #"/C tf.exe status /collection:http://tiffany:8080/tfs/ /user:* /format:detailed >c:\\Status\\Detailed.txt";
this.process = new Process();
this.process.StartInfo.FileName = #"cmd.exe";
this.process.StartInfo.Arguments = arguments;
this.process.Start();
Edit:
If that's all your console app does, why not consider creating a batch (.BAT / .CMD) file instead of a C# application?
Instead of running a command line tool you could leverage the TFS API.
There are many articles out there, e.g. Code project article on topic
and
Sample code directly from the MSDN
I suppose you have to read standard error and output from process started:
Process process = new Process();
process.StartInfo.Arguments = #"status PATH /recursive";
process.StartInfo.FileName = "tf.exe";
process.StartInfo.CreateNoWindow = false;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
var st = process.StandardOutput.ReadToEnd();
var err = process.StandardError.ReadToEnd();
But parsing tf output is not easy and I'd like to suggest to use TFS API as #Mare said
You do not need to create an application in C # to save in a text file. Just use the parameters (...) > [file name].txt at the end of the command.
The ">" symbol send the result of any command to a file.

Using Drush Site-Install in C#

I'm trying to do a Drupal site install using Drush in C# as part of a full Windows Server site installation using MSI.
The Drush commmand I am using is the following one.
C:\ProgramData\Drush\Drush.bat -y si application_name --db-url=sqlsrv://admin_name:password(local)\SQLEXPRESS:/database_name --account-name=admin --account-mail=name#test.com --account-pass=Password1234 --site-mail="admin#company.com" --site-name="Site Name" install_configure_form.site_default_country=GB install_configure_form.date_default_timezone="Europe/London"
And this works perfectly when run from cmd.exe when in the working directory (inetpub\application_name).
The issue arises when the above is put into code and executed during an installation and always results in the following error (with a different file name each time).
Unable to decompress C:\ProgramData\Drush\lib\druFD63.tmp.gz
The C# code being used to execute the command is as follows:
public static ActionResult Drush_Configuration(Session session)
{
string strArgs = "-y si application_name --db-url=sqlsrv://admin_name:password(local)\SQLEXPRESS:/database_name --account-name=admin --account-mail=name#test.com --account-pass=Password1234 --site-mail="admin#company.com" --site-name="Site Name" install_configure_form.site_default_country=GB install_configure_form.date_default_timezone="Europe/London";
string strExeCmd = #"C:\ProgramData\Drush\Drush.bat ";
strExeCmd = strExeCmd + strArgs;
string strLocation = #"C:\inetpub\application_name";
session.Log("Starting Drush Configuration");
session.Log("Command line is: " + strExeCmd + " " + strArgs);
int exitCode;
ProcessStartInfo processInfo;
Process process;
try
{
processInfo = new ProcessStartInfo("cmd.exe", "/c " + strExeCmd);
processInfo.WorkingDirectory = strLocation;
processInfo.WindowStyle = ProcessWindowStyle.Normal;
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
// *** Redirect the output ***
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
process = Process.Start(processInfo);
process.WaitForExit();
// *** Read the streams ***
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
exitCode = process.ExitCode;
session.Log("output>>" + (String.IsNullOrEmpty(output) ? "(none)" : output));
session.Log("error>>" + (String.IsNullOrEmpty(error) ? "(none)" : error));
session.Log("ExitCode: " + exitCode.ToString(), "ExecuteCommand");
process.Close();
}
catch (Exception e)
{
session.Log("Error: " + e);
return ActionResult.Failure;
}
session.Log("Drush Configuration completed successfully");
return ActionResult.Success;
}
And as stated above, this always results in the "unable to decompress" error.
Has anyone ever used c# to run Site-Install in Drush? Does anyone know why this might fail when executed in this way?
Any thoughts or advice would be greatly appreciated.
I am using Drush-5.8-2012-12-10-Installer-v1.0.20, Drupal 7, and Windows Server 2008 R2 x64.
The cause of this issue was the Environment Variables. The Drush MSI installer sets up User Path Environment Variables which are not recognized in an MSI machine context.
So, by adding System Path Variables for Drush, GnuWin32 and PHP to the site-install MSI the site can be programmatically installed.

Categories