Process.Start working directory in the same string as filepath - c#

Is there any way to specify working directory as below?
Process.Start("c:\someDir\someExecutable.exe + working directory path");
or how to make windows environment variable path work with :
Process.Start("c:\someDir\someExecutable.exe");
I know that ProcessStartInfo can be use to specify working directory.
I have my own reason to for wanting to put working directory and file path in same parameter of Process.Start().

The documentation for public static Process Start(string fileName) is found here: https://msdn.microsoft.com/en-us/library/53ezey2s(v=vs.110).aspx
As you can see the description for that parameter is:
The name of a document or application file to run in the process.
The remarks also note:
This overload does not allow command-line arguments for the process. If you need to specify one or more command-line arguments for the process, use the Process.Start(ProcessStartInfo) or Process.Start(String, String) overloads.
So in summary no, you can't do this. Even if your program accepted a working directory as a command line argument this overload will not work.

Related

How to get the calling directory of a C# assembly?

I am trying to write a small build event utility to read the current assembly version of my code.
Thus, I want that executable to be in my %PATH% (or some central location at least) and be able to take a relative path to my target assembly as an argument (to Assembly.LoadFile() it) but Assembly.LoadFile() complains about receiving a relative path.
How can I do:
C:\calling\path>mytool rel\path\to\target.exe
Without having to type C:\devpath\to\mytool.exe every time?
And be able to get the string "C:\calling\path\rel\path\to\target.exe" in mytool.exe?
It turns out that this is a bit of a pain.
A C# assembly requires its support files to be in the same directory as itself so in the simple case, we can't just copy the exe to our chosen directory.
Another possibility is to create a shortcut to the exe and move that to the directory. Unfortunately, despite having an impressive amount of "current" path getters, C# doesn't have a way to know if it's been started through a shortcut.
When invoked from a shortcut in C:\calling\path, all of the following:
Console.WriteLine(Environment.CurrentDirectory);
Console.WriteLine(Directory.GetCurrentDirectory());
Console.WriteLine(Assembly.GetEntryAssembly().Location);
Console.WriteLine(System.AppDomain.CurrentDomain.BaseDirectory);
Console.WriteLine(System.AppContext.BaseDirectory);
//Console.WriteLine(Process.GetCurrentProcess().StartInfo.WorkingDirectory);
Console.WriteLine(Process.GetCurrentProcess().MainModule.FileName);
Console.WriteLine(Environment.GetCommandLineArgs()[0]);
return a variation of "C:\devpath\to". Except for Process.StartInfo which just crashes. You can't get the StartInfo of a process you didn't Process.Start(), including your own.
The only way that appears to work to be able to retrieve "C:\calling\path" is to create a batch file in "C:\inpath" that calls the original assembly directly.
So:
C:\inpath\exe.bat:
C:\devpath\to\mytool.exe %*
C:\devpath\to\mytool.cs:
Console.WriteLine(Environment.CurrentDirectory);
Console.WriteLine(Directory.GetCurrentDirectory());
These 2 will return "C:\calling\path".
Another option could be to add C:\devpath\to itself to the PATH

Calling .bat file from c#

Using this piece of code .exe running in server
string bat =null;
bat = "D:/folder/a.bat";
System.Diagnostics.Process.Start(bat);
Error: Could not find the specified file.
Can anyone help me on this.
Make sure the file really is located at that path.
Make sure your program has access to this path.
Use backslashes: bat = #"D:\folder\a.bat";
Filepath in Windows doesn't take a forward slash, it's not a URL/URI.
Use backslashes.
Anyone of below should work if the program has access to the bat file.
string bat=#"D:\folder\a.bat";
or
string bat="D:\\folder\\a.bat";
Also, checking for the existence of the bat file will be a good practice here:
if(File.Exists(bat))
{
System.Diagnostics.Process.Start(bat);
}
change the slashes to backslashes:
bat = "D:\\folder\\a.bat";
Typically you need to run an executable (like cmd.exe) and then pass it a parameter. cmd.exe specifically has two options /C (carries out the command specified by the string, then terminates) and /K (carries out the command specified by the string but remains open)
Wrong path. Try
bat = #"D:\folder\a.bat";

Using WritePrivateProfileString to write path issue

I am using WritePrivateProfileString in c# (through DllImport) to store paths taken from textboxes on the interface. And the .ini file name is hardcoded in my application
string ini_file = ".\\config.ini";
However, when the file writing happens, the configuration file is written to the first path taken from the interface instead of writing it to the exe directory. Which is quite odd.
Debugging shows that the values are sent correctly to the WritePrivateProfileString but it still is written to the wrong location. Anyone knows why is that happenening?
I'd guess that something is changing the working directory of your process, most likely your code in the process. Note that the documentation has this to say:
If the lpFileName parameter does not contain a full path and file name for the file, WritePrivateProfileString searches the Windows directory for the file. If the file does not exist, this function creates the file in the Windows directory.
Now my guess is that this applies if you supply just a file name. Because your file name starts with . I believe that will force the function to start from the current working directory.
Having said all of that, and no matter what the cause of the problem is, you should use a fully-qualified path in order to make sure the file is written where you want it to be written. Whenever you want the file to go in a specific directory, it's always easiest to force that by using fully-qualified paths.
You can find the path to your executable using Application.ExecutablePath and then remove the file name part.
Another point to make is that the same directory as the executable may be a bad choice. If your program is installed under the Program Files directory then the directory which contains the executable will not be generally writeable. I think you should consider using a directory under in the user profile. Look for one of the Environment.SpecialFolder values.
Further to David Heffernan's answer - you can use
Path.GetDirectoryName(Application.ExecutablePath);
to safely get just the running application's folder part.
If you're in a dll rather than an executable, you can use
Path.GetDirectoryName(Assembly.GetAssembly(typeof(MyClass)).CodeBase);
Both require System.IO, and were originally posted here. Second example also requires System.Reflection).
Application data files are supposed to be written to the LocalApplicationData special folder.
string path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData);
You typically will not have permissions to write into the Program Files folder etc.

Launching a .pl file using Process.Start

I have been using Process.Start to launch executables (.exe) files. Now I need to execute a .pl file with some arguments. can I still use Process.Start or I need a different approach?
EDIT :- I am having to mark this question unanswered as I am getting the following error when I try to call the perl file from the CSharp code:- (When I call the same from the commandline with the same path and parameters, It works fine)
System.ApplicationException: StartProcess Failed
System.ComponentModel.Win32Exception: The specified executable is not a valid application for this OS platform)
Please note that when I try to call an .exe file from my C# code, I dont see the above error.
EDIT:-
Checking the following link now:- How do I call Perl script in C# application?
It seems that the ProcessStartInfo constructor has two parameters - fileName and the arguments. You should set Perl.exe as the fileName and the "argument" would be your perl file (.pl) with other arguments It accepts. Checking now....
You certainly can :) you can also pass it arguments by adding them after the file name in
Process.Start(file.pl args1 args 2);
It will load the file with your default application for .pl files, the other option is to specify the software then pass your file as a parameter providing you have the right software to handle the file it should be fine
Process.Start() can be pointed at any file and it will be opened using the default software or that which you specify, it need not be an executable.
Yes you can, Process.Start() takes a string parameter, what you pass for this parameter does exactly the same thing it would do if you entered the same string in the windows start -> run dialog.

Getting the absolute path of the executable, using C#?

Have a look at this pseudocode:
string exe_path = system.get_exe_path()
print "This executable is located in " + exe_path
If I build the above program and place the executable in C:/meow/, It would print out This executable is located in C:/meow/ each time it is run, regardless of the current working directory.
How could I easily accomplish this using C#?
MSDN has an article that says to use System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase; if you need the directory, use System.IO.Path.GetDirectoryName on that result.
Or, there's the shorter Application.ExecutablePath which "Gets the path for the executable file that started the application, including the executable name" so that might mean it's slightly less reliable depending on how the application was launched.
AppDomain.CurrentDomain.BaseDirectory
using System.Reflection;
string myExeDir = new FileInfo(Assembly.GetEntryAssembly().Location).Directory.ToString();
var dir = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
I jumped in for the top rated answer and found myself not getting what I expected. I had to read the comments to find what I was looking for.
For that reason I am posting the answer listed in the comments to give it the exposure it deserves.
"Gets the path or UNC location of the loaded file that contains the manifest."
See: http://msdn.microsoft.com/en-us/library/system.reflection.assembly.location.aspx
Application.ResourceAssembly.Location
Suppose i have .config file in console app and now am getting like below.
Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName + "\\YourFolderName\\log4net.config";
On my side, I used, with a form application:
String Directory = System.Windows.Forms.Application.StartupPath;
it takes the application startup path.
The one that worked for me and isn't above was Process.GetCurrentProcess().MainModule.FileName.
If you are planning to build a console application to be used with Task Scheduler, I'd recommend using this approach:
var execDirectoryPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)?.Replace("file:\\", "");
This way, the path will adapt to whatever location you place your executable file in.

Categories