Wrapper for a Command Line Tool in C#
Asked Answered
F

2

6

Using MSDN I got the class to write a wrapper for my command line tool.

I now am facing a problem, if I execute the exe through the command line with arguments, it works perfect without any errors.

But when I try to pass the arguments from the Wrapper it crashes the program.

Wanted to know if I am passing the arguments properly and if I am wrong, could somebody point out please. This is the LaunchEXE class from MSDN

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;

namespace SPDB
{
    /// <summary>
    /// Class to run any external command line tool with arguments
    /// </summary>
    public class LaunchEXE
    {
        internal static string Run(string exeName, string argsLine, int timeoutSeconds)
        {
            StreamReader outputStream = StreamReader.Null;
            string output = "";
            bool success = false;

            try
            {
                Process newProcess = new Process();
                newProcess.StartInfo.FileName = exeName;
                newProcess.StartInfo.Arguments = argsLine;
                newProcess.StartInfo.UseShellExecute = false;
                newProcess.StartInfo.CreateNoWindow = true; //The command line is supressed to keep the process in the background
                newProcess.StartInfo.RedirectStandardOutput = true;
                newProcess.Start();
                if (0 == timeoutSeconds)
                {
                    outputStream = newProcess.StandardOutput;
                    output = outputStream.ReadToEnd();
                    newProcess.WaitForExit();
                }
                else
                {
                    success = newProcess.WaitForExit(timeoutSeconds * 1000);

                    if (success)
                    {
                        outputStream = newProcess.StandardOutput;
                        output = outputStream.ReadToEnd();
                    }
                    else
                    {
                        output = "Timed out at " + timeoutSeconds + " seconds waiting for " + exeName + " to exit.";
                    }
                }
            }
            catch (Exception e)
            {
                throw (new Exception("An error occurred running " + exeName + ".", e));
            }
            finally
            {
                outputStream.Close();
            }

            return "\t" + output;           

        }
    }
}

This is the way I am passing arguments from my main program (Form1.cs)

private void button1_Click(object sender, EventArgs e)
        {
            string output;
            output = LaunchEXE.Run(@"C:\Program Files (x86)\MyFolder\MyConsole.exe", "/BACKUP C:\\MyBackupProfile.txt", 100);
            System.Windows.Forms.MessageBox.Show(output);
        }

The command line tool accepts the following command and works perfectly:

C:\Program Files (x86)\MyFolder>MyConsole.exe /BACKUP C:\MyBackupProfile.txt

Formyl answered 12/3, 2013 at 12:0 Comment(7)
When you say "crashes the program", do you get an exception, error message, something else?Stranger
Just the program crashes, I have log files for that command line tool, but it is not built by me... I got a reply from the developer of that tool that it is my fault and his tool is working well. But this is what I got out of the the tool's log file..."System.NullReferenceException: Object reference not set to an instance of an object." however I do not get any exception error in my program...Formyl
A breakpoint at newProcess.Start(); itself crashes the program..Formyl
If I were you and I do not have access to the tool I would make dummy exe that just log the received parameters in both cases to make sure I do the right thing here.Liszt
Thank you @MahmoudFayez I will do that, still new at programming..Thank you for the tip.Formyl
Maybe the program "MyConsole.exe" uses the working directory to find a file or something and I think that if you do not specify the StartInfo.WorkingDirectory it uses the one of the calling program. Is the only difference I see from calling "MyConsole.exe" from a console. So you can try adding newProcess.StartInfo.WorkingDirectory = Directory.GetParent(exeName).FullName;Ronald
Take a look at how the process is actually invoked, by using something as Process Explorer (Microsoft tool, previously Sysinternals). This way you'll get to see exactly how the parameters are passed.Parlour
C
2

I have two options for you -

1) Please try running your Visual Studio on "administrator mode". or 2) Try to implement this instead. https://github.com/commandlineparser/commandline.

"The Command Line Parser Library offers to CLR applications a clean and concise API for manipulating command line arguments and related tasks. It allows you to display an help screen with an high degree of customization and a simple way to report syntax errors to the user. Everything that is boring and repetitive to be programmed stands up on library shoulders, letting you concentrate yourself on core logic. This library provides hassle free command line parsing with a constantly updated API since 2005."

Worked great for me.

Cistern answered 12/3, 2013 at 16:6 Comment(0)
M
0

I have a feeling it doesn't like the spaces in your path. See this post: C# How to use Directory White Spaces into process.arguements?

Materially answered 12/3, 2013 at 14:33 Comment(2)
I did think so too...but I did try with escape characters in it and still failed. Plus I tried to find out whether it was something to do with permissions.. As even executing cmd with parameters fail to execute, only cmd invoking works. Can this be a problem with permissions? However thank you for the link @MatthewEvansFormyl
I have a Windows 7 Home premium and installed VS 2010 on it. Do I have to set some kind of permission within VS to have rights to folder/files on the system.Formyl

© 2022 - 2024 — McMap. All rights reserved.