MSDEPLOY using CMD with C# script in Visual Studio - c#

I am tryin got execute a msdeploy.exe command using cmd from visual studio with c# as scripting language
string filename = #"C:\Deploy\Test\Test.zip";
string servername = #"PADEVSPTAPP";
string compname = #"IIS Web Application Name";
string appvalue = #"Test";
string strCmdText;
strCmdText = "msdeploy.exe -verb:sync -source:package=" + filename + " -dest=auto,computerName=" + servername + " -setParam=name=" + compname + ",value=" + appvalue + " -allowUntrusted";
//System.Diagnostics.Process.Start("CMD.exe", strCmdText);
try
{
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("cmd", "/c " + strCmdText);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
string result = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
Console.WriteLine(result);
}
catch (Exception objException)
{
Console.WriteLine(objException.ToString());
}
the string outcome is
msdeploy.exe -verb:sync -source:package="C:\\Deploy\\Test\\Test.zip"
-dest=auto,computerName="PADEVSPTAPP" -setParam=name="IIS Web Application Name",value="Test" -allowUntrusted
but this does not work due to \\ in the command.
How should i execute this command.
I even tried with powershell script ,which also did not work
string PS_script = #"$msdeploy = ""C:\\Program Files\\IIS\\Microsoft Web Deploy V3\\msdeploy.exe""
$package = """;
PS_script = PS_script + Row.deployfile;
PS_script = PS_script + #"""
$compname = ""PADEVSPTAPP""
$appname = ""IIS Web Application Name""
$appvalue = """;
PS_script = PS_script + changetype[0];
PS_script = PS_script + #"""
$md = $(""`""{0}`"" -verb:sync -source:package=`""{1}`"" -dest=auto,ComputerName=`""{2}`"" -setParam=name=`""{3}`"",value=`""{4}`"" -allowUntrusted"" -f $msdeploy, $package, $compname, $appname, $appvalue)
cmd.exe /C ""`""$md`""""";
I have no clue where I am going wrong.

You are using an equals sign where it should be colon.
It's supposed to be -dest: and not -dest=
Same with setParam, it's supposed to be -setParam: not -setParam=
I suspect you don't actually have double backslashes \\ in your string it will just look like that if you inspect via the debugger - I suspect thats whats throwing you off.
Since you have spaces in your compname variable you need double quotes in your arguments string (probably around all your variables would be a good idea).
Also try running msdeploy.exe directly instead of via cmd.exe /c.
I assumed your msdeploy.exe is located in C:\Program Files (x86)\IIS\Microsoft Web Deploy V3
The string outcome is:
-verb:sync -source:package="C:\Deploy\Test\Test.zip" -dest:auto,computerName="PADEVSPTAPP" -setParam:name="IIS Web Application Name",value="Test" -allowUntrusted
Put it all together:
string filename = #"C:\Deploy\Test\Test.zip";
string servername = #"PADEVSPTAPP";
string compname = #"IIS Web Application Name";
string appvalue = #"Test";
string strCmdText;
strCmdText = "-verb:sync -source:package=\"" + filename + "\" -dest:auto,computerName=\"" + servername + "\" -setParam:name=\"" + compname + "\",value=\"" + appvalue + "\" -allowUntrusted";
//System.Diagnostics.Process.Start("CMD.exe", strCmdText);
try
{
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo(#"C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe");
procStartInfo.Arguments = strCmdText;
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
string result = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
Console.WriteLine(result);
}
catch (Exception objException)
{
Console.WriteLine(objException.ToString());
}
BONUS INFO
If you need a more bulletproof way of determining where msdeploy.exe is located maybe have a look at these links:
https://gist.github.com/SergeyAxenov/15cf008531e6d0741533
How to find out what version of webdeploy/msdeploy is currently installed?

Related

The process tried to write to a nonexistent pipe when running cmd.exe using c#

I tried to call a .exe program I have calling cmd from a c# script that generates a command. When I run the code I get the output the process tried to write to a nonexistent pipe. But when I run said command using a cmd open from Windows it runs perfectly. What I am doing wrong? I am using Visual Studio 2022.
SilentMkdir(baseDir + "/00_CameraInit");
string binName =pre + binDir + "\\aliceVision_cameraInit.exe";
string dstDir =pre + baseDir + "/00_CameraInit\\";
string cmdLine = binName;
cmdLine = cmdLine + " --defaultFieldOfView 45.0 --verboseLevel info --sensorDatabase \"\" --allowSingleView 1";
cmdLine = cmdLine + " --imageFolder \"" + pre + srcImageDir + "\"";
cmdLine = cmdLine + " --output \"" + dstDir + "cameraInit.sfm\"";
Console.WriteLine(cmdLine);
var processInfo = new ProcessStartInfo("cmd.exe", cmdLine);
processInfo.UseShellExecute = false;
processInfo.RedirectStandardOutput = true;
processInfo.CreateNoWindow = false;
//processInfo.RedirectStandardOutput = !string.IsNullOrEmpty("output.txt");
int exitCode = -1;
string output = null;
try
{
var process = Process.Start(processInfo);
process.Start();
output = process.StandardOutput.ReadToEnd();
Console.WriteLine(output);
process.WaitForExit();
}
catch (Exception e)
{
Console.WriteLine("Run error" + e.ToString()); // or throw new Exception
}

PGP decryption command not outputting file - process.StandardInput.WriteLine(sCommandLine);

public string DecryptFile(string encryptedFilePath)
{
const string quote = "\"";
FileInfo info = new FileInfo(encryptedFilePath);
string decryptedFileName = info.FullName.Substring(0, info.FullName.IndexOf(".pgp") + 4);
//decryptedFileName = info.FullName.Replace(".pgp", "");
decryptedFileName = decryptedFileName.Replace(this.txtFolderPath, this.txtFolderPath + "\\ProcessedZip\\");
//decryptedFileName = "C:\\pgpTest\\ProcessedZip\\"+ info.Name;
decryptedFileName = decryptedFileName.Replace(".pgp", "");
decryptedFileName = quote + decryptedFileName + quote;
string encryptedFileName = quote + info.FullName + quote;
string password = "thisisnottherealpassword";
System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo("cmd.exe");
psi.CreateNoWindow = true;
psi.UseShellExecute = false;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.WorkingDirectory = this.txtFolderPath;
System.Diagnostics.Process process = System.Diagnostics.Process.Start(psi);
string sCommandLine = "gpg.exe --pinentry-mode=loopback --passphrase \"" + password + "\" -d -o --batch --verbose --yes --output " + decryptedFileName + #" --decrypt " + encryptedFileName;
process.StandardInput.WriteLine(sCommandLine);
process.StandardInput.Flush();
process.StandardInput.Close();
process.WaitForExit();
//string result = process.StandardOutput.ReadToEnd();
//string error = process.StandardError.ReadToEnd();
process.Close();
return decryptedFileName;
}
The above code works in a separate project but having it utilized by another layer of the application through binaries is not spitting out a decrypted file. I'm not sure why as no errors seem to be thrown and using the commandline string in my own command line will correctly run the process.
Any thoughts on why this could be?

How can I take ownership of a file in c# using takeown or icacls?

I know there are other posts on the matter but none have presented me with a working solution.
I'm trying to take ownership of files under C:\Windows\Media so I can replace them with my own. Currently I've been trying to do that by running either takeown or icacls in CMD, but neither seem to work. The takeown method actually returns success from CMD but I still get access denied when trying to delete the file. With the icacls method I get "the handle is invalid" and still get access denied.
The program is running as administator fyi.
And also in the icacls method changing Environment.Username to "Administrators" doesn't change anything.
Any help is appreciated!
Here is the code for the takeown method:
string[] soundFiles;
soundFiles = Directory.GetFiles(#"C:/Windows/Media", "*.wav");
//string cmdargs = #"/c takeown /F C:\Windows\Media";
string shortcmdargs = #"/c takeown /F ";
//Process.Start("CMD.exe", cmdargs);
string output = "null";
foreach(string file in soundFiles)
{
try
{
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = shortcmdargs + #"C:\Windows\Media\" + Path.GetFileName(file);
p.Start();
output = p.StandardOutput.ReadToEnd();
System.IO.File.Delete(file);
System.IO.File.Copy("neco.wav", file);
}
catch(Exception exce)
{
MessageBox.Show("Output: " + output + "\neException: " + exce);
}
}
And here is what I get when running it:
Here is the code for the icacls method:
string[] soundFiles;
soundFiles = Directory.GetFiles(#"C:/Windows/Media", "*.wav");
string cmdargs = #"/c takeown /F C:\Windows\Media";
string shortcmdargs = #"/c takeown /F ";
Process.Start("CMD.exe", cmdargs);
string output = "null";
foreach(string file in soundFiles)
{
try
{
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = #"/c icacls " + #"C:\Windows\Media\" + Path.GetFileName(file) + " /grant " + Environment.UserName + ":(OI)(CI)F /T";
p.Start();
output = p.StandardOutput.ReadToEnd();
System.IO.File.Delete(file);
System.IO.File.Copy("neco.wav", file);
}
catch(Exception exce)
{
MessageBox.Show("Output: " + output + "\neException: " + exce);
}
}
And here is what I get with it:

.NET webservice attemp to print on a network printer not working

I am working on a c# web service using .net framwork 4.0
and I have a file (print.exe) which executes printing, the file works when I double click it manually, it prints, but when using the webservice it give an error that No printer installed.
this the code of the webmethod:
[WebMethod]
public String Print_In_Kitchen(Int32 OrderID, String Lang)
{
System.Security.SecureString secPass = new System.Security.SecureString();
string paswd = "96321";
for (int i = 0; i < paswd.Length; i++)
{
secPass.AppendChar(paswd[i]);
}
Process proc = new Process();
proc.StartInfo.FileName = #"C:\EXE_Print.exe";
proc.StartInfo.Arguments = #"" + OrderID + " " + Lang + " " + "\"" + ConfigurationManager.ConnectionStrings["constr"].ConnectionString + "\"";
proc.StartInfo.UserName = "omar";
proc.StartInfo.Password = secPass;
proc.StartInfo.Domain = "Futec";
proc.StartInfo.Verb = "runas";
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.Verb = "runas";
proc.StartInfo.RedirectStandardInput = true;
proc.Start();
string s = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
return s;
}
I have searched for a solution but haven't found any useful link or explanation for this, saw this question here but with no answer:pdf print through .net process
and I am new to .NET
My gut feeling is that the User that the Service is running as, doesn't have access to that printer.
You could try changing StartInfo.UseShellExecute to true but I would also check the permissions of your services user.

How to create a RAM Disk with imdisk and C#?

I'm trying to create a RAM Directory via imdisk in C#. Since the cmd command is something like: imdisk -a -s 512M -m X: -p "/fs:ntfs /q /y"
I looked up how to process cmd commands with C# and found several hints regarding ProcessStartInfo(). This class works almost the way I intend it to, but since imdisk needs administrator priviliges I'm kinda stuck. Even though the code block is executed without exceptions, I don't see any new devices within the Windows Explorer.
try
{
string initializeDisk = "imdisk -a ";
string imdiskSize = "-s 1024M ";
string mountPoint = "-m "+ MountPoint + " ";
string formatHdd = "-p '/fs:ntfs /q /y' ";
SecureString password = new SecureString();
password.AppendChar('0');
password.AppendChar('8');
password.AppendChar('1');
password.AppendChar('5');
ProcessStartInfo procStartInfo = new ProcessStartInfo();
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
procStartInfo.RedirectStandardError = true;
procStartInfo.FileName = "cmd";
procStartInfo.Verb = "runas";
procStartInfo.UserName = "Admin";
procStartInfo.Password = password;
procStartInfo.Arguments = initializeDisk + imdiskSize + mountPoint + formatHdd;
Process.Start(procStartInfo);
catch (Exception objException)
{
Console.WriteLine(objException);
}
I hope someone can give me a little hint, right now I'm out of ideas.
Well I solved my problem in a different way. Somehow it seems that imdisk didn't format the new RamDisk the way it should and therefor no disk were created. As soon as I deleted the formatting option the disk is created and needs to be formatted. Therefore I started another process and used the cmd command "format Drive:"
For anyone who is interested, my solution is as follows:
class RamDisk
{
public const string MountPoint = "X:";
public void createRamDisk()
{
try
{
string initializeDisk = "imdisk -a ";
string imdiskSize = "-s 1024M ";
string mountPoint = "-m "+ MountPoint + " ";
ProcessStartInfo procStartInfo = new ProcessStartInfo();
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
procStartInfo.FileName = "cmd";
procStartInfo.Arguments = "/C " + initializeDisk + imdiskSize + mountPoint;
Process.Start(procStartInfo);
formatRAMDisk();
}
catch (Exception objException)
{
Console.WriteLine("There was an Error, while trying to create a ramdisk! Do you have imdisk installed?");
Console.WriteLine(objException);
}
}
/**
* since the format option with imdisk doesn't seem to work
* use the fomat X: command via cmd
*
* as I would say in german:
* "Von hinten durch die Brust ins Auge"
* **/
private void formatRAMDisk(){
string cmdFormatHDD = "format " + MountPoint + "/Q /FS:NTFS";
SecureString password = new SecureString();
password.AppendChar('0');
password.AppendChar('8');
password.AppendChar('1');
password.AppendChar('5');
ProcessStartInfo formatRAMDiskProcess = new ProcessStartInfo();
formatRAMDiskProcess.UseShellExecute = false;
formatRAMDiskProcess.CreateNoWindow = true;
formatRAMDiskProcess.RedirectStandardInput = true;
formatRAMDiskProcess.FileName = "cmd";
formatRAMDiskProcess.Verb = "runas";
formatRAMDiskProcess.UserName = "Administrator";
formatRAMDiskProcess.Password = password;
formatRAMDiskProcess.Arguments = "/C " + cmdFormatHDD;
Process process = Process.Start(formatRAMDiskProcess);
sendCMDInput(process);
}
private void sendCMDInput(Process process)
{
StreamWriter inputWriter = process.StandardInput;
inputWriter.WriteLine("J");
inputWriter.Flush();
inputWriter.WriteLine("RAMDisk for valueable data");
inputWriter.Flush();
}
public string getMountPoint()
{
return MountPoint;
}
}
Doesn't cmd.exe need to have the /C command line option passed through to run a command passed through as an argument? May well be that cmd.exe is just ignoring what you're passing through in procStartInfo.Arguments because you haven't prepended "/C " onto the front of the Arguments.

Categories