Execute OS Command on a file C# - c#

I am trying to execute a OS command through C#. I have the following code taken from this webpage:
//Execute command on file
ProcessStartInfo procStart =
new ProcessStartInfo(#"C:\Users\Me\Desktop\Test\System_Instructions.txt",
"mkdir testDir");
//Redirects output
procStart.RedirectStandardOutput = true;
procStart.UseShellExecute = false;
//No black window
procStart.CreateNoWindow = true;
//Creates a process
System.Diagnostics.Process proc = new System.Diagnostics.Process();
//Set start info
proc.StartInfo = procStart;
//Start
proc.Start();
but when I attempt to run the code I get the following error:
{"The specified executable is not a valid application for this OS platform."}
What am I doing wrong? I have tried this example as well but got the same issue.

The overload of the ProcessStartInfo constructor you are using expects an executable file name and parameters to pass to it - a .txt file is not executable by itself.
It sounds more like you want to execute a batch file with commands within the file. For that check this SO thread: How do I use ProcessStartInfo to run a batch file?

Try setting the USESHELLEXECUTE member to TRUE instead of FALSE.
It worked for me - but I think this has reprocussions for certain users after publishing.

You are trying to execute a TXT file. That's why you get
{"The specified executable is not a valid application for this OS platform."}
Because, well, the specified executable (TXT) is not a valid application for this OS platform.

You would target an executable or other file that has a specified opening application. You're targeting a text file; what you should do is target Notepad, and then supply the path to your text file as an argument:
ProcessStartInfo info = new ProcessStartInfo
{
FileName = "C:\\Windows\System32\\notepad.exe",
Arguments = "C:\\Users\\Me\\Desktop\\Test\\System_Instructions.txt"
}
new Process.Start(info);
Alternatively, if you mean for your text file to be executed, it needs to be made a .bat file.

You are trying to execute this:
C:\Users\Me\Desktop\Test\System_Instructions.txt mkdir testDir
The shell has no clue how to "execute" a text file so the command fails.
If you want to execute this text file as a batch file, change file extension to .bat so the system understands it's a batch file, and then set UseShellExecute so it does the default action for it (= runs it, in case of a batch file).

If you want to open up the file in Notepad, use:
ProcessStartInfo procStart =
new ProcessStartInfo("notepad.exe", #"C:\Users\Me\Desktop\Test\System_Instructions.txt");
If you want to write into the file :
//In case the directory doesn't exist
Directory.CreateDirectory(#"C:\Users\Me\Desktop\Test\);
using (var file = File.CreateText(#"C:\Users\Me\Desktop\Test\System_Instructions.txt"))
{
file.WriteLine("mkdir testDir");
}
If you have commands in the text file that you want to execute, just rename it to .bat and it should work (and presumably the contents do something with "mkdir testDir" as a parameter?)

What are you trying to accomplish?
Create a directory? Use the "System.IO.Directory.CreateDirectory" method.
Open a .txt file with associated program? Use ProcessStartInfo(#".\filename.txt") with UseShellExecute set to true. This will cause the associated program for that file type to be executed, which might not be notepad.txt.

Related

Process.start with application & filename as variables

Have been searching, but surprisingly could not find this specific question:
With C# I want (by clicking a button in a form) to run a certain file, with an certain application.
When using "Process.start(variable)" I can only pick one of the two.
And by using "Process.startinfo.filename" (like: https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.filename?view=net-5.0) this also seems to be the case.
Isn't is possible to just combine both in some "easy" way?
Thanks.
Typically you would run a file with an application using a command argument (i.e. 'notepad.exe file.txt').
If that is possible with the application(s) you are attempting to launch, then you would simply need to set the Filename property of StartInfo to the name, if in the PATH, or the full path of the application and the Arguments property to the path of the file.
var process = new Process();
process.StartInfo.FileName = "notepad.exe";
process.StartInfo.Arguments = "C:\\{pathToFile}\\file.txt";
process.Start();
The above code would launch notepad opening file.txt. You can simply replace the FileName and Arguments with variables containing the paths to the application and file.

Executing directory

I have a C# program that is running and I want to launch another executable in different directory.
I have this code on event:
string path = "Y:\Program\test.exe";
Process.Start(path);
Problem is that in order for program to work right it need to take information from settings.ini where the exe file is located but it takes settings.ini from program folder with which I am trying to launch second program. test.exe is working fine when I am opening it from its folder by double click. What could be the problem?
You need to tell the process what the working directory is via ProcessStartInfo.WorkingDirectory:
var processStartInfo = new ProcessStartInfo
{
WorkingDirectory = #"Y:\Program",
FileName = #"Y:\Program\test.exe",
};
Process.Start(processStartInfo);
Edit:
In order to get the directory from the user, you can use DirectoryInfo.FullName:
var userFileInfo = new FileInfo(userInsertedVariableHere);
var parentDirectory = userFileInfo.Directory.FullName;

Adding a script file in a Visual Studio 2010 C# application

I am writing a C# program that needs to run a script. I want to include the script with the application so that it is available when the user installs the program after I publish it.
I tried adding the script as a resource. In the Solution Explorer, under the Resources directory, I can see the script file.
In the program, I call a function that starts a process and runs the desired command:
runNewProcess("tclsh \\Resources\\make.tcl " + activeProducts);
I get the command prompt with the message "couldn't read file "\Resources\make.tcl": no such file or directory". So I guess it cannot find the file? Am I not referencing the file correctly? Is this the correct way of doing something like this?
Thank you all for your suggestions. Using them and with a bit more research, I was able to come up with a perfect solution for me.
1) Add the TCL script file as a resource to the project and set the Build Action to 'Content' in it's Properties.
2) Get the path to the TCL script (even after installation from a published version):
string makeScriptPath = System.Windows.Forms.Application.StartupPath + "\\Resources\\make.tcl";
3) Construct the run command using all the required variables and pass it to a routine that can execute it.
localCommand = String.Format("tclsh \"{0}\" --librarytype {1} --makeclean {2} --buildcode {3} --copybinary {4} --targetpath \"{5}\" --buildjobs {6} --products {7}",
makeScriptPath, library, makeClean, buildCode, copyBinary, targetPath, buildJobs, activeProducts);
runNewProcess(localCommand);
where:
private void runNewProcess(string command)
{
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("cmd", "/k " + command);
procStartInfo.RedirectStandardOutput = false;
procStartInfo.UseShellExecute = true;
procStartInfo.CreateNoWindow = true;
// Now we create a process, assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
}
This gives some added perks. Since the file is included with the application, but remains a separate entity, this allows it to be tweaked and modified without needing to re-build, re-publish and re-install the application.
The script runner is unable to dig into you executable to find the commands, as it most likely only know what to do with files on disk. Shipping as a resource is a good idea, but for make anything useful with it you should extract it into a real file on disk so that other programs can use it.
A good pattern for such things would be to create a temporary file on %TEMP%, make the script runner execute that file, and delete it afterwards.
To expand on Alejandro's answer, The easiest way to handle this is to use the temporary folder and copy your script there first.
var scriptPath = Path.Combine(Path.GetTempPath(), "make.tcl");
// Copy the text of the script to the temp folder. There should be a property
//you can reference associated with the script file if you added the file using
//the resources tab in the project settings. This will have the entire script in
//string form.
File.WrteAllText(scriptPath, Resources.make);
runNewProcess("tclsh \"" + scriptPath + "\"" + activeProducts); //added quotes in case there are spaces in the path to temp.
File.Delete(scriptPath); //Clean up after yourself when you are done.
You need to ensure that the Build Action of the script file is set to Content to keep it as an independent file. By default it will be set to Resource which means you will have to programmatically extract it and then save it to a temporary location before attempting to run it.

C# - Open a file with the associated program without invoking the command line

Is it possible to open a file with the default program without invoking the command line? I want to run a unit test and have the unit test open the file (PDF) at completion for visual inspection.
Just call Process.Start(filePath).
This will open the file in the user's default program.
I think this should work:
System.Diagnostics.Process.Start(#"c:\file.pdf"); //i.e provide the full path!
Simply use the following syntax:
System.Diagnostics.Process.Start(#"c:\yourfile.txt");
Process process = new System.Diagnostics.Process();
process.EnableRaisingEvents = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.FileName = filePath;
string arguments = fileArguments;
process.StartInfo.Arguments = fileArguments;
process.Start();
process.WaitForExit();
This way you can invoke and put the file name in the pdf with parameters/arguments. You can also specify different programs and put it in the path, then the pdf name in the fileArguments. It's up to you.
if you use this code:
System.Diagnostics.Process.Start( "C:\...\...\myfile.pdf" );
the pdf should get opened by the default program associated to the .pdf extension.
is this what you wanted? I would be careful in putting this inside the unit test in case you include those tests in an automated build on the server, which runs with no logged in user, this could be an issue if it fails and if it does not fail, who is there to close Acrobat Reader? :D

Open a file with Notepad in C#

How I open a file in c#? I don't mean reading it by textreader and readline(). I mean open it as an independent file in notepad.
You need System.Diagnostics.Process.Start().
The simplest example:
Process.Start("notepad.exe", fileName);
More Generic Approach:
Process.Start(fileName);
The second approach is probably a better practice as this will cause the windows Shell to open up your file with it's associated editor. Additionally, if the file specified does not have an association, it'll use the Open With... dialog from windows.
Note to those in the comments, thankyou for your input. My quick n' dirty answer was slightly off, i've updated the answer to reflect the correct way.
You are not providing a lot of information,
but assuming you want to open just any file on your computer
with the application that is specified for the default handler for that filetype,
you can use something like this:
var fileToOpen = "SomeFilePathHere";
var process = new Process();
process.StartInfo = new ProcessStartInfo()
{
UseShellExecute = true,
FileName = fileToOpen
};
process.Start();
process.WaitForExit();
The UseShellExecute parameter tells Windows to use the default program for the type of file you are opening.
The WaitForExit will cause your application to wait until the application you luanched has been closed.
this will open the file with the default windows program (notepad if you haven't changed it);
Process.Start(#"c:\myfile.txt")
System.Diagnostics.Process.Start( "notepad.exe", "text.txt");
You can use Process.Start, calling notepad.exe with the file as a parameter.
Process.Start(#"notepad.exe", pathToFile);
Use System.Diagnostics.Process to launch an instance of Notepad.exe.

Categories

Resources