I do not know if this is even possible without breaking/crashing the process but is there a way to change the working directory of a System.Diagnostics.Process like you would when executing the cd (change directory) command from the cmd.exe command line interface?
You may set the working directory of the process with
myProcess.StartInfo.WorkingDirectory = "dir".
Documentation here.
As per MSDN, there is only one function which can change current folder, SetCurrentDirectory and it has single string parameter, so the change is for current process only.
Related
If I connect to a running process by extracting it using Process.GetProcessesByName("Notepad");, is it possible to reconstruct that processĀ“s ProcessStartInfo?
I would for example want to be able to attach to Notepad, Kill it and Start it again. Without a valid ProcessStartInfo the Start call will fail.
There is no direct support for this.
You can go over each property of the running process and initialize a ProcessStartInfo object with the corresponding values.
No, there are cases where that's not possible. A simple example is:
Process.Start("example.lnk");
No way to find out later that a .lnk file was used to get the process started.
The WorkingDirectory is a tricky one, a process often requires it to be set correctly but might change it later. A process that got started with a different user account is insurmountable, no way you can provide the correct account password. A custom environment is yet another one.
To put it simply, if process A starts application B.
Whenever application B tries to do a relative file access such as
using(StreamReader sr = new StreamReader("log.txt"))
It accesses log.txt in the folder that process A is inside of, not the folder that application B is inside of.
Right now my current fix for this is to get my application's module file name + path, remove the file name and prepend the path variable onto all my relative file access calls.
What causes this and how can I avoid it?
In process A, where you launch application B, you should have specified the working folder.
Take a look at this: http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.workingdirectory.aspx
EDIT (after clarification from OP that process A is the task scheduler, and therefore cannot be modified)
I think the task scheduler allows you to specify the working directory for the application that you schedule. But in any case, even if you cannot, you can always set the current directory of your application to the right place first thing as soon as it starts, using SetCurrentDirectory().
Once you have access to the Process, you can try getting the Module. From here, you can access the full path of the process (using the FileName property) and, in turn, its directory.
string fullPath = myProcess.Modules[0].FileName;
string workingDirectory = System.IO.Directory.GetParent(fullPath);
According to this thread, 32-bit modules won't be able to enumerate modules of 64-bit assemblies, so you'll need to recompile your program to 64-bit if your target processes will be running in that mode.
I want to determine the absolute path of files used by a known process by reading the command line. Currently, the process is started with relative paths in the command line that point to various files such as config files. The problem is that if the paths are not relative to the folder containing the executable, I have no way of converting the relative paths provided at the command line, well I can't be 100% sure.
For example two batch files:
BATCH 1
CD c:\test\bin
test.exe ..\config\config.ini
BATCH 2
CD c:\test
bin\test.exe config\config.ini
For batch file one, the command line I get is "c:\test\bin\test.exe ..\config\config.ini" and for batch file two I get "c:\test\bin\test.exe config\config.ini". So, see this I can't resolve the paths.
Anyway for starters, I got the command line from a WMI query using ManagementObjectSearcher. Now I need to get the working directory the process was started from to resolve the paths passed at the command line but how?
EDIT: I forgot one key detail. I want to get the working directory of another process. Basically, my main program gathers info from another program. I'm able to determine the process ID because I know the name of the executable. I can also determine the command line. I must now find the working directory or current directory the executable was started in so I can resolve the relative paths of command line. I hope I made the question clearer.
I think Environment.CurrentDirectory should give you the directory the executable was started in. It is only reliable at the start of the process, because it can change later.
Or maybe try Process.GetCurrentProcess().StartInfo.WorkingDirectory. I didn't try it myself, just looked it up on MSDN
To get working directory (current directory) of another process in c# take a look at https://stackoverflow.com/a/23842609/3029359
Have you tried Application.ExecutablePath?
Alternatively, there are numerous Paths that can be retrieve from Application
Imagine I have a picture viewer application made with C# and .NET. I have already set the preferred application to view pictures to use the C# application.
I want to somehow let my program know where it has been invoked. How can I achieve this?
If you're using it to view pictures via shell associations, you can just check the picture filenames passed in on the command line. You can use Environment.GetCommandLineArgs to get the first filename:
// Should check to make sure there is at least one filename passed first...
string imageFilename = Environment.GetCommandLineArgs[1];
string directory = System.IO.Path.GetDirectoryName(imageFilename);
If you want the working directory, just check Environment.CurrentDirectory at startup...
I think you can use Environment.CurrentDirectory
The current directory (Environment.CurrentDirectory) of an application can change during execution. Additionally, the current directory may not be the directory in which the application resides, such as if a user runs it from a command line in an arbitrary directory by specifying an absolute path to the executable.
If you really want the "current directory" of the application, then use Environment.CurrentDirectory, but if you want to know the location of the application, you can use the following approaches:
System.Windows.Forms.Application.ExecutablePath
(if running a WinForm application)
System.Windows.Forms.Application.StartupPath
(if running a WinForm application)
System.Reflection.Assembly.GetEntryAssembly().Location
Here's the situation: I am trying to launch an application, but the location of the .exe isn't known to me. Now, if the file extension is registered (in Windows), I can do something like:
Process.Start("Sample.xls");
However, I need to pass some command line arguments as well. I couldn't get this to work
Process p = new Process();
p.StartInfo.FileName = "Sample.xls";
p.StartInfo.Arguments = "/r"; // open in read-only mode
p.Start();
Any suggestions on a mechanism to solve this?
Edit # aku
My StackOverflow search skills are weak; I did not find that post. Though I generally dislike peering into the registry, that's a great solution. Thanks!
Using my code from this answer you can get command associated with xls extension. Then you can pass this command to Process.Start method.
If you query the registry, you can retrieve the data about the registered file type and then call the app directly passing the command line arguments. See Programmatically Checking and Setting File Types for an example of retrieving shell information for a file type.