Run DOS Command from C# program

Hello Experts,
I am trying to run a set of DOS commands from C# program, which need to be executed in a Windows Service.  It runs fine in Development machine and Test Server.  But when I deploy that in Production, it does not run.  When I say it does not run, only DOS portion does run.  The C# part runs just fine.  Any idea, what is going on?  Is there a way I can capture any exception?  Any help is highly appreciated.

Thank you very much in advance.
RadhaKrishnaKiJayaAsked:
Who is Participating?
 
Chinmay PatelEnterprise ArchitectCommented:
I almost wrote this in the last comment itself, why you are using ThreadStart. Process is a right solution for this problem. Now, I see you just spawn a thread and then call Process.Start so  I can suggest that you hook up the following two properties and dump whatever is happening with your command line.

https://msdn.microsoft.com/en-us/library/system.diagnostics.process.standarderror(v=vs.110).aspx

https://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput(v=vs.110).aspx

This will tell us what is happening when your DOS files execute.

Regards,
Chinmay.
0
 
Chinmay PatelEnterprise ArchitectCommented:
Can you clarify which part does not run? Also can you post your code?
0
 
Shaun VermaakTechnical Specialist/DeveloperCommented:
If you use a library such as TopShelf, you can run it as a console by just running the EXE, a service by registering it and debugging it is easier. If this is not an option, post some code.
http://topshelf-project.com/
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
Ryan ChongCommented:
It runs fine in Development machine and Test Server.
so if same program was being deployed and run perfectly into Production Server, technically it should runs perfectly as well.

try check the security settings in Production Server in which it may prevent some executables to be run.

Is there a way I can capture any exception?
Have you catch the InnerException?

Exception.InnerException Property
https://msdn.microsoft.com/en-us/library/system.exception.innerexception(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2
0
 
RadhaKrishnaKiJayaAuthor Commented:
Ryan,Chinmay and Shaun,
Thank you very much for your time and help.  Please note, this is a Windows Service program.

Chinmay, Please look at the code.  I have added my comments.

Shaun, I am not allowed to download anything into production box.  Any other ideas?

Ryan,
I think the issue is with Security Settings too.  How can I run DOS commands as an Administrator directly from the program?  
FYI, when I run the same commands directly in the Command Prompt, it works just fine.  

Thank you all for your help.

       public bool UploadReportFile()
        {
            string UserName = ConfigurationManager.AppSettings["UN"];
            string Password = ConfigurationManager.AppSettings["Pwd"];

            string NetworkPath = ConfigurationManager.AppSettings["OutPutPath"];
            DateTime CurrentDate = DateTime.Now;
            DateTime dYesterday = CurrentDate.AddDays(-1);

            string ReportName = dYesterday.Month.ToString().Trim() + dYesterday.Day.ToString() + DateTime.Now.Year.ToString().Substring(2, 2) + "MCR" + ".csv";
            string NewReportName = dYesterday.Month.ToString().Trim() + dYesterday.Day.ToString() + DateTime.Now.Year.ToString().Substring(2, 2) + "MCR" + ".csv";

            string OutPutFile = NetworkPath + '"' + ReportName + '"';
            string NewOutPutFile = NetworkPath + NewReportName;

            try
            {
                bool returnVal = false;
                string RunDosCommandPath = ConfigurationManager.AppSettings["RunDosCommandPath"];
                string ChangeDirectory = "CD " + RunDosCommandPath;
                string XferCommandVbsScriptFile = ConfigurationManager.AppSettings["XferCommandVbsScriptFile"];
                string XferCommandTxtScriptFile = ConfigurationManager.AppSettings["XferCommandTxtScriptFile"];

                StreamWriter txtFile = new StreamWriter(RunDosCommandPath + "/" + XferCommandTxtScriptFile);

                txtFile.Write(UserName + "\r\n");
                txtFile.Write(Password + "\r\n");
                txtFile.Write("mput " + NewOutPutFile + "\r\n");
                txtFile.Write("quit");
                txtFile.Close();

                StreamWriter vbsFile = new StreamWriter(RunDosCommandPath + "/" + XferCommandVbsScriptFile);
                vbsFile.Write("const DontWaitUntilFinished = false, ShowWindow = 0, DontShowWindow = 0, WaitUntilFinished = true" + "\r\n");
                vbsFile.Write("\r\n");
                vbsFile.Write(@"Set oShell = CreateObject(""Wscript.Shell"")" + "\r\n");
                vbsFile.Write("\r\n");
                vbsFile.Write("Dim strArgs1, strArgs2" + "\r\n");
                vbsFile.Write("\r\n");
                vbsFile.Write(@"strArgs1 = ""cmd /c call xfer.exe -s:xfer.txt DestintionServerName  > ErrorOutput.txt""" + "\r\n");
                vbsFile.Write(@"strArgs2 = ""cmd /c call del xfer.txt""" + "\r\n");
                vbsFile.Write("\r\n");
                vbsFile.Write("oShell.Run strArgs1, DontShowWindow, WaitUntilFinished" + "\r\n");
                vbsFile.Write("oShell.Run strArgs2, DontShowWindow, WaitUntilFinished" + "\r\n");
                vbsFile.Close();

                string[] cmdarr = new string[] { ChangeDirectory, DeleteExistingOutPutFile, RenameOutPutFile, XferCommandVbsScriptFile };
                string filename = System.AppDomain.CurrentDomain.BaseDirectory + "testcmd.cmd";

                // Everything works till here.  
                // DOS Commands does not work from here. Still the Debug message is posted in the log file.

                WriteContentToFile(filename, cmdarr);
                System.Threading.Thread objThread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(RunCMDScript));
                objThread.IsBackground = true;
                objThread.Priority = System.Threading.ThreadPriority.AboveNormal;
                objThread.Start(filename);

                log.Debug("Though the above 5 lines don't work, still this message is posted in my Log file...");

                return returnVal;
            }
            catch (Exception ex)
            {
                log.Debug("Error in uploading the file: ", ex);
            }
            return false;
        }
0
 
Chinmay PatelEnterprise ArchitectCommented:
Please remove confidential information.
0
 
Shaun VermaakTechnical Specialist/DeveloperCommented:
Shaun, I am not allowed to download anything into production box.  Any other ideas?
Geeze, not even NuGet packages. That doesn't sound right
https://www.nuget.org/packages/topshelf
0
 
Chinmay PatelEnterprise ArchitectCommented:
Hi,

I think that is correct... instead of a direct download, the build should be generally in that order


Dev -> Test/QA ->  Build/Integration -> UAT/Pre-Prod -> Prod.

I know not all the projects follow this but many a times it is strictly prohibited to expose Prod servers to downloads.

Please post the code of RunCDMScript. Also I do not see if you are tracking what is happening to objThread?
Couple of other pointers, have you checked all the batch/script files are generated properly? Once they are generated, try to execute them from the command line.

Regards,
Chinmay.
0
 
RadhaKrishnaKiJayaAuthor Commented:
Chinmay,
Here is the code.  All the batch scripts I can see the right directory soon after I start the service.

Thank you!

        private static void RunCMDScript(object scriptPath)
        {
            System.Diagnostics.ProcessStartInfo procStartInfo =
                                       new System.Diagnostics.ProcessStartInfo(scriptPath.ToString());
            // Now we create a process, assign its ProcessStartInfo and start it
            System.Diagnostics.Process proc = new System.Diagnostics.Process();
            proc.StartInfo = procStartInfo;
            proc.Start();
        }
0
 
RadhaKrishnaKiJayaAuthor Commented:
Chinmay,  Thank you. I will rewrite the code using Process.  Before that, is there a way to know why it is not executing the DOS commands?  Is there a way to catch the exception?

Hey, thank you for letting me know about the confidential information.  I already did it.

Thank you!
0
 
Chinmay PatelEnterprise ArchitectCommented:
No worries :)

And no need to rewrite the entire thing, just modify your RunCMDScript. And in RunCMDScript, where you have written


Before that

proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
string output = proc.StandardOutput.ReadToEnd(); // This will capture whatever your files produce when they are run on DOS prompt
string error = proc.StandardError.ReadToEnd(); // This will capture if there are any errors during the execution of DOS commands

// Write above two strings to event log or some file so you can read what is the error and what is the output

Open in new window


This will tell us what is going on during the execution of your process.

Regards,
Chinmay.
0
 
RadhaKrishnaKiJayaAuthor Commented:
Hello Chinmay,  Thank you for your help.  Your posts helped me a lot to fix the issue.  Thank you again!
0
 
Chinmay PatelEnterprise ArchitectCommented:
I am glad I could help :)
0
All Courses

From novice to tech pro — start learning today.