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
Related
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.
I have a file that I store some site links. Until now I used:
string path = Environment.CurrentDirectory + "/forumlinks.txt";
But I want to store the file in the release folder so I can change it and I know it will change permanently for the user.
So I changed to this:
string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + #"/forumlinks.txt";
But I get an exception:
System.IO.FileNotFoundException.
My question: is this the right way to get the file from the release folder? Should I rethink that and store him in a different place? If so I will be glad to hear about it.
I don't see the reason why you would need to call the
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location))
at all. This does the trick:
AppDomain.CurrentDomain.BaseDirectory
Hard coding a path to your code release folder is dangerous. What if you want to build in debug mode for some reason? What happens when you want to deploy your program?
A better choice would be to use the environment's application data folder. This will be different for each user, so it means that each user can have their own version of the file.
See this post for details of how to get the application data folder.
Well assuming the forward / is a typo.
If you've added the test file to your project, check it's properties, needs to be copy if newer / copy always to put it in bin\Debug or bin\Release, with the exe and dlls and other gubbins.
Why are you doing it this way, are you planing for something to change the file, without having to rebuild the application?
i made a mistake and found out that it was right to use this code:
string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\fourmlinks.txt";
if you put the right name of the file, and still get an exception that mean that the file is not in the correct place.
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 have created a form with FileBrowse control to load a file from.
the problem is, after i load a file the application looks for files in the path i'v selected instead of the 'Debug' directory (where files should be...)
how can i avoid it ? is it normal behavior ?
You can avoid it by not relying on the current directory being anything. Just consider what happens if you create a shortuct to your application, and change the startup directory.
If you want the directory where the application is why do you look for the current directory? You can get the directory of the application with the following:
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
If this is a Windows Forms application, you can get it much easier:
Application.StartupPath
Answered Here: Why does OpenFileDialog change my working directory?
And Here: Why the current working directory changes when use the Open file dialog in Windows XP ?
This beahviour is part of Windows Common Controls (OpenFileDialog) and has nothing to do with your application configuration.
However, you can set the initial directory in your application.
Check the control for a property called RestoreDirectory. Is this set to True? If yes, try it as false.
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