Executing directory - c#

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;

Related

Running a batch file in relative path?

There is a batch file which I want to run it when I press the button.
My code works fine when I use absolute (full) path. But using relative path causes to occur an exception.
This is my code:
private void button1_Click(object sender, EventArgs e)
{
//x64
System.Diagnostics.Process batchFile_1 = new System.Diagnostics.Process();
batchFile_1.StartInfo.FileName = #"..\myBatchFiles\BAT1\f1.bat";
batchFile_1.StartInfo.WorkingDirectory = #".\myBatchFiles\BAT1";
batchFile_1.Start();
}
and the raised exception:
The system cannot find the file specified.
The directory of the batch file is:
C:\Users\GntS\myProject\bin\x64\Release\myBatchFiles\BAT1\f1.bat
The output .exe file is located in:
C:\Users\GntS\myProject\bin\x64\Release
I searched and none of the results helped me. What is the correct way to run a batch file in relative path?!
The batch file would be relative to the working directory (i.e. f1.bat)
However, your working directory should be an absolute path. It is not guaranteed whichever path is current for your application (may be set in .lnk). In particular it's not the exe path.
Sou you should use the path of your exe file as obtained from AppDomain.CurrentDomain.BaseDirectory (or any other well known method) to build the path of your batch file and/or working directory.
Finally - use Path.Combine to determine a correctly formatted path.
According to JeffRSon`s answer and comments by MaciejLos and KevinGosse my problem was solved as below:
string executingAppPath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
batchFile_1.StartInfo.FileName = executingAppPath.Substring(0, executingAppPath.LastIndexOf('\\')) + "\\myBatchFiles\\BAT1\\f1.bat";
batchFile_1.StartInfo.WorkingDirectory = executingAppPath.Substring(0, executingAppPath.LastIndexOf('\\')) + "\\myBatchFiles\\BAT1";
An alternative way is:
string executingAppPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
batchFile_1.StartInfo.FileName = executingAppPath.Substring(6) + "\\myBatchFiles\\BAT1\\f1.bat";
batchFile_1.StartInfo.WorkingDirectory = executingAppPath.Substring(6) + "\\myBatchFiles\\BAT1";
I report it here hoping help somebody.

Search for a specific ".exe" and open programatically [duplicate]

This question already has answers here:
When running a program using Process.Start, it can't find it's resource files
(2 answers)
Closed 6 years ago.
I want my program to search a users computer for a file called "xonotic.exe" and open it. Xonotic is a video game if that helps. Inside it's parent folder it contains many other contents that .exe uses on launch.
// Prepare the process to run
ProcessStartInfo start = new ProcessStartInfo();
// Enter the executable to run, including the complete path
start.FileName = #"C:\Users\Landon\Desktop\Xonotic\xonotic.exe";
start.WindowStyle = ProcessWindowStyle.Hidden;
start.CreateNoWindow = false;
Process.Start(start);
When I run my program in vs with this code it launches "xonotic.exe" but (here's what it looks like). That is a print of the screen on launch and if it looks like the text is going off the edge of my screen its because it is; what you see is what I see.
When I exit vs and just open "xonotic.exe" as I would normally it launches perfectly. My question is why would the programmatic way and the manual way open the same .exe in two different ways? Also when I get out of the buggy xonotic and hover over the icon to see the full view it says that you have reached this menu due to missing or unlocatable content/data. (You can see what I'm talking about here). Also if this part can be resolved easily is there a way to search for the .exe without having to know the filepath? I figured something like this would be super easy, all I want to do is launch program but it has been giving me a lot of grief.
Set the WorkingDirectory property first, then you may also try to set UseShellExecute property as well if needed:
string pathToExecutable = #"C:\Users\Landon\Desktop\Xonotic\xonotic.exe";
var startInfo = new ProcessStartInfo()
{
FileName = pathToExecutable,
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = false,
WorkingDirectory = System.IO.Path.GetDirectoryName(pathToExecutable),
UseShellExecute = true
};
UPDATE:
You can search on all drive in all folders, but this would be very time consuming. Here is the code for that:
string[] drives = Directory.GetLogicalDrives();
string pathToExecutable = String.Empty;
foreach (string drive in drives)
{
pathToExecutable =
Directory
.EnumerateFiles(drive, "xonotic.exe", SearchOption.AllDirectories)
.FirstOrDefault();
if (!String.IsNullOrEmpty(pathToExecutable))
{
break;
}
}
if (String.IsNullOrEmpty(pathToExecutable))
{
// We did not find the executable.
}
else
{
// We found the executable. Now we can start it.
}
You have here 3 different question, maybe give them numbers for each question.
And about your third question-
you must have a path of the root and then you can search for all the exe files in the subfolders
string PathOfEXE = #"C:\"; //or d:\ or whatever you want to be the root
List<string> fileEntries = Directory.GetFiles(PathOfEXE , "*.exe",
System.IO.SearchOption.AllDirectories).ToList();
Directory.GetFiles(PathPractice, "*.exe", System.IO.SearchOption.AllDirectories).ToList();
System.IO.SearchOption.AllDirectories).ToList();
foreach (string fullPathfileName in fileEntries)
{
string fileName =System.IO.Path.GetFileName(fullPathfileName )
if (fileName=="xonotic.exe"){ //your code goes here
string pathToExecutable = fullPathfileName ;
}
}

Capture the directory path it uses to run the program

I have a C# application which assume it runs from bin directory
string current_directory = Directory.GetCurrentDirectory(); //get current directory, this is the bin dir
string parent_dir = Directory.GetParent(current_directory).ToString();// this is parent of bin dir
string _Config1 = parent_dir + "\\config\\x.cfg";
string _Config2 = parent_dir + "\\config\\y.cfg";
string _Log = parent_dir + "\\log\\z.log";
The problem is for some reasons the user can not go to the bin directory and run the app (just type "application_name"). He has to run it using path (ie d:\blah\1\blah\2\blah\3\bin\application_name)
when he does this he gets
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Lo‌​cation)
so either I have to capture the path he uses to run the program and use it in my program or somehow make my application to be able to run using path.
You can use AppDomain.CurrentDomain.BaseDirectory.
Use the Application.StartupPath for WinForms.
You can use reflection:
var path = System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().GetName().GetCodebase );

Execute OS Command on a file 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.

Use relative Path in Microsoft Surface application?

I convert my wave file into a mp3 file by the following code:
internal bool convertToMp3()
{
string lameEXE = #"C:\Users\Roflcoptr\Documents\Visual Studio 2008\Projects\Prototype_Concept_2\Prototype_Concept_2\lame\lame.exe";
string lameArgs = "-V2";
string wavFile = fileName;
string mp3File = fileName.Replace("wav", "mp3");
Process process = new Process();
process.StartInfo = new ProcessStartInfo();
process.StartInfo.FileName = lameEXE;
process.StartInfo.Arguments = string.Format("{0} {1} {2}", lameArgs, wavFile, mp3File);
process.Start();
process.WaitForExit();
int exitCode = process.ExitCode;
if (exitCode == 0)
{
return true;
}
else
{
return false;
}
}
This works, but now I'd like to not use the absolut path to the lame.exe but a relative path. I included a lame.exe in the folder /lame/ on the root of the project. How can I reference it?
If you have rights to distribute the file with your application, then one way of doing it would be to include the .exe file as an item in your C# project, with
Build Action = None
Copy to Output Directory = Copy if newer
You can then just use
string lameEXE = #"lame.exe"
Assuming your binary app is in Debug folder and the lame folder is in the main project directory:
string lameEXE = #"..\..\lame\lame.exe
Hovewer, folders structure will be probably different in your release version.
Directly using a path relative to the application directory is a bad idea since the working directory might not be identical to the application directory. This can lead to bugs and security holes. For example you might execute files in untrusted directories.
Some cases where the working directory isn't identical to the application directory:
The user opens a file from the explorer. Then the working directory is the directory where the file is in
Depending on the settings Common Dialogs(OpenFileDialog, SaveFileDialog) change the working directory.
So you should expand it relative to the project directory. Unfortunately I know of no clean library function which does that for you. In simple cases this can be done by concatenating the relative path to the application directory:
string appDir = Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]) + "\\";
const string relativePath=#"..\..\lame.exe";//Whatever relative path you want
string absolutePath=appDir+relativePath;
...
process.StartInfo.FileName =absolutePath;
...

Categories

Resources