Starting application with shortcuts (%PROGRAMFILES%) being used - c#

I'm wondering is there any way to use the normal shortcuts form windows like %PROGRAMFILES%, %APPDATA%,.... when using System.Diagnostics.Process.Start ?
What I want to do there is using one of those shortcuts to dynamically create the path that is being used to tart the program I want to start with Process.Start.
Example:
System.Diagnostics.Process.Start("%PROGRAMFILES%\MyApp\MyApp.exe");
Edit: As a comment to the accepted answer:
As one important thing was mentioned in the comments I want to also put it here:
If the solution does not work as the file is not found, one should print out the result of the System.Environment.ExpandEnvironmentVariables command. It can be that it points unintendedly to the x86 program files location instead of the program files location (or vice versa) depending on if for the application itself (project properties) "Prefer 32-bit" or platform target is set accordingly. If that is kept in mind the solution works quite nicely.

Use System.Environment.ExpandEnvironmentVariables to perform the expansion first, then pass the result to Process.Start:
System.Diagnostics.Process.Start(
System.Environment.ExpandEnvironmentVariables(#"%PROGRAMFILES%\MyApp\MyApp.exe"));

I am almost sure this does not work, however, there is an environment class in the .NET library that can return the information you are looking for.
Probably like:
// Change the directory to %WINDIR%
Environment.CurrentDirectory = Environment.GetEnvironmentVariable("windir");
If you use 'programfiles' instead it might work (could not check here).

You can use
Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)`
To get the path to a special folder (in this case, 32-bit program files directory). There's more in that class that would be of help as well.
Also, I expect that Process.Start with the non-expanded path will work fine if you use UseShellExecute - the shell is capable of expanding paths on its own.
However, this is still probably a bad solution. What if the user installed your target application somewhere else? Are you sure there's no better way to get path to the application?

Related

visual c# button opens file without specifying drive

I work for an IT company where we all carry around flash drives that have our most used programs on them.In my spare time I am hoping to create a "main menu" item that is kind of a fun and convenient way to access these files. I am working on creating this using Visual Studio 2013 and using visual C# windows forms. I have come across a snag however that I can't seem to find a workaround for. I am by no means fluent in C#, but I need to have a button on the windows form open a file without specifying what drive it comes from. I understand that I have to specify a path, but as these will be stored on the flash drives of myself and my coworkers I cannot foresee that the path will always begin with E:. Depending on what USB slot the drive is plugged into it could be N: or F: or the like. I have provided an example below:
Using what I currently know I am opening files using this line of code:
System.Diagnostics.Process.Start("C:/Users/Myname/Desktop/Asmodeus/Anti-Virus/Anti-Virus Installers/avast_free_antivirus_setup.exe");
Is there any way possible I can have the file open simply from
System.Diagnostics.Process.Start("Asmodeus/Anti-Virus/Anti-Virus Installers/avast_free_antivirus_setup.exe");
or something of that nature?
Thanks in advance.
There must have been some mis-communication when I asked my question previously. what I am looking to do is open an executable file via a button click on the windows form using a relative path. I am not able to specify the absolute path because the application will be run from a flash drive and therefore will change depending on what USB slot it is currently inserted into.
What I am hoping to accomplish is insert a line of code that will allow me to open an executable file that is located in the \bin\debug folder along with the application itself. I have a picture for clarification but apparently do not have enough reputation to post it. Thank you and sorry for the earlier confusion.
Usually you can just use Environment.GetFolderPath (MSDN) to give you what you need. It doesn't do absolutely everything, but if you need Desktop and the like, that is plenty.
Depending on the target version of .Net, the SpecialFolders exposed are not all there. It may turn out that you need more than they provide, but in your case it doesn't sound like it.
If there is more you need that is not covered in the default, check out this project. I'm sure there are others like it, but it does a little more than the default BCL version, using the API directly. It is at least something to read and learn (and translate from vb.. use an online translator, very quick). I haven't looked at it, but it seems like you are learning this c#/.net thingy, so it might be helpful
This article is about accessing Windows special folders.
These folders include your “Favorites”, “Cookies”, system libraries and the like.
Here is code, including a large number of constant definitions, plus documentation,
allowing access to and creation of these folders.

Significance of a PATH explained

This is probably a rudimentary question but I am still kinda new to programming and I've wondered for awhile. I've done multiple projects in Python, C#, and Java, and when I try to use new libraries (especially for Python) people always say to make sure its in the right PATH and such. I just followed an online tutorial on how to install Java on a new computer and it rekindled my question of what a path really is. Is the Path just were the programming language looks for a library in the file system? I get kinda confused on what it's significance is. Again, I'm sorry for the wide question, its just something that I've never quite gotten on my own programming.
EDIT: I just wanted to thank everyone so much for answering my question. I know it was a pretty dumb one now that I've finally figured out what it is, but it really helped me. I'm slowly working through as many C#, Java and Python tutorials as I can find online, and it's nice to know I have somewhere to ask questions :)
The PATH is an environment variable which the shell (or other command interpreter) uses to search for commands. Usually (always?) commands are found with a greedy algorithm, so entries that come first in the PATH are returned first. For example, a command in /usr/local/bin will override a command in /usr/bin given a PATH such as
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
while the purpose is consistent, the syntax is slightly different on WINDOWS - you would use
C:\> ECHO %PATH%
to "echo" your PATH.
First my shell is going to search /usr/local/sbin then /usr/local/bin then /usr/sbin and then /usr/bin before searching /sbin and /bin if the command isn't found then it will report that it couldn't find such a command...
# Like so
$ thisprogramdoesntexist
thisprogramdoesntexist: command not found
Now, on Linux at least, there's also a LD_LIBRARY_PATH which the system will use to search for dynamic libraries (greedily), on Windows I think it just uses the PATH. Finally, Java uses a CLASSPATH which is similar (but used to search for classes and JARs).
On Linux one might add an entry to the PATH like so,
$ export PATH="$PATH:/addNewFolder"
While on Windows you might use
set PATH=%PATH%;c:\addNewFolder
Sometimes, you might manipulate your PATH(s) to enable specific functionality, see update-java-alternatives on Ubuntu for an example.
A PATH is a file directory on your computer. If you need to install a programming language, you might need to put it in your system PATH variable. This means that the system looks to these files for different information, IE where the libraries for the code you are using are.
Hope that helped!
Exactly as other said, PATH is a list of folders that is included in the search -other than the current folder- and you can always access straight away. It's one of the Environment Variables.
For example, we have the python folder in C:\Python27. I'm sure you know that to run a python file, we commonly use python script.py.
What happens is that the command line searches for python.exe in your current folder, and if not found, search it in the folders in the path variable.
To read the path, you can, straightforwardly use:
$ PATH
If you're on windows, like i am, an easy way to deal with this is to just use System Properties. Just type it in the start menu, open it, and go to the 'advanced' tab. Click on the Environment Variables, there! You'll see a PATH variable, and you can modify it as you want.
I myself use more than one version of Python, and to deal with this, i appended all the folders to PATH, and changed my python.exe to pythonversion_number.exe. Problem solved! Now, i can run this in the command line:
$ python26 script.py
$ python33 script2.py
Some further reading on this, if you're interested, here's a good question asked
Hope this helps!
The best resource (so far) about PATH information, you can see in this question:
https://superuser.com/questions/284342/what-are-path-and-other-environment-variables-and-how-can-i-set-or-use-them
Stack Overflow is not the best place to search about this, always check the amazing
https://superuser.com/ for this kind of question.
PATH is a symbolic name usually associated to string values separated by a semicolons (where each string part is a directory name). This symbolic name (and its values) is handled by the operating system and could be modified by the end user through the some command line instruction like SET PATH=........ or through some kind of user interface configuration tool.
It is common practice for tools like compilers or other programming tools to look at this symbolic name and use the list of string values for searching files that are not directly available in the current folder used by the tools.
So, if an installation procedure set the PATH symbol in this way
SET PATH=%path%;C:\PROGRAM FILES\MYTOOLFOLDER;
it means, set the PATH symbol to the previous value (%PATH%) and add another string value to it (C:\PROGRAM FILES\MYTOOLFOLDER).
Then the tool, when it needs to search for a particular file or library, could read the PATH symbol values, split them at the semicolons and iteratively look at the directories listed one by one looking for the file required.
In C# programming, for example, the tool code could contain something like this
string pathSymbol = Environment.GetEnvironmentVariable("PATH");
string[] pathFolders = pathSymbol.Split(';');
foreach(string folder in pathFolders)
{
if(File.Exists(Path.Combine(folder, "mylibrary.dll"))
{
..... do whatever you need to do with the file
}
}
This example assumes a Windows environment.

How to get full path to file that "knows" when working in debugger

I have an XML file I'm streaming as an XDocument. I need to be able to get the full path of the file (NOT the bin/Debug path) using reflection or the like (so this will be the path from the User's machine it lives on).
I have tried about a zillion different ways, including:
System.Reflection.Assembly.GetCallingAssembly().Location
System.Reflectin.Assembly.GetEntryAssembly().Location
System.Reflection.GetExecutingAssembly().Location
AppDomain.CurrentDomain.BaseDirectory.
How do I look use System.IO to find the path on the User's machine to my file?? Quite suprised I haven't found the simple answer after googling all day.
::EDIT:: I've now found out that there is no way to "reflectively" locate a path dynamically based on whether the application is running in the debugger or not. My only option is to do some detection.
Thanks in advance!!
I'm assuming that the file is in a child directory of the executable?
You can get the full path of the current working directory (ie where your .exe was run from) by using the Environment class. You can then concatanate this with the child directory
Environment.CurrentDirectory + #"\folder\file.xml"
http://msdn.microsoft.com/en-us/library/system.environment.aspx
Hope this helps!
EDIT: After reading up a little it turns out that CurrentDirectory can be changed rather easily. The accepted answer here Environment.CurrentDirectory is yielding unexpected results when running installed app offers a more reliable method.
Found my answer here (using path stripping and GetFullPath() ). It's a real bummer there's no way around just stripping the bin/debug part of the path. I used the third part of the question linked above.

Refresh start menu icons in Windows 8

I have an application that works weirdly: the setup process copies the files to a temp folder, then checks a few things, and if everything is ok, moves the files to the final folder.
The problem is that the installer creates the shortcuts before the files are moved.
The result is that on the start menu (the one with the tiles), the icon is the "default sortcut" one.
I have tried to force the refresh of the system using this link (broadcast a WM_SETTINGCHANGE message) but it doesn't seem to work for the Windows 8 start menu.
Even rebooting the OS doesn't seem to refresh the icon, the only thing that works is to reinstall the soft on top of itself.
How can I force the icons refresh for the Win8 start menu ?
Thanks
First off, you don't tell us why your install process needs to work the way that it does. I agree that's weird, but I assume you have a good reason for doing it that way. If not, I suggest starting there and fixing the installer rather than putting band-aids on individual problems. You're bound to run into other problems later, and the root fix is bound to be much simpler and easier to maintain than a bunch of band-aids.
Anyway, if you must go down this path… The reason that broadcasting a WM_SETTINGCHANGE message doesn't work is because this doesn't have anything to do with icons. Those are managed separately by Explorer and don't get rebuilt unless you delete its icon cache. That, naturally, prompts it to rebuild it. It's a common troubleshooting technique for end users, but it's not something you want to do programmatically. Talk about an ugly hack. And altering the global state to solve a local problem.
Besides, if rebooting the OS doesn't work, you know it's not as simple as you make it sound in your question: a property in need of a refresh. The reason that reinstalling on top of the existing installation works is because when the shortcut gets created in the beginning, its target executable already exists in the expected place (put there by the previous installation) with a valid icon.
What I recommend doing is writing some code to change the icon of the existing shortcut. Make sure that you execute it after you've copied the executable file to its final destination. The method that allows you to do that is IShellLink::SetIconLocation, which takes two parameters: a path to the icon (this would be the path to your executable file), and the index of the icon (this would probably be 0 assuming that the icon you want is the first and only one contained in the executable).
Of course, in order to call SetIconLocation, you're going to have to obtain an object representing your shortcut that implements IShellLink. This is a COM interface, which I don't believe is wrapped anywhere by the .NET Framework. General information on creating shortcuts from C# is available in the answers to this question. More specifically, there's a link to this wrapper class that you can use to do most of the dirty work. I don't think it contains a method for setting/changing the icon, but that can be trivially added.
Alternatively, you can get at these same properties using the Windows Scripting Host (WSH) wrapper, WshShortcut. It has an IconLocation property that works much the same way except that it takes only a single string argument, with the index delimited from the path by a comma: myApp.exe, 0. It's not particularly well documented (best I can find), but to get an existing shortcut, you just use the CreateShortcut method and specify the path to the existing shortcut. For example:
public void SetShortcutIcon(string shortcutPath, string iconPath, int iconIndex)
{
// Note: no error checking is performed for the parameters!
// This is not production-ready code!
// If a shortcut does not exist at the specified path, you should
// create a new one instead.
// If iconPath does not specify a valid executable file, you should
// set a default icon or perhaps abort.
IWshRuntimeLibrary.WshShell wsh = new IWshRuntimeLibrary.WshShell();
IWshRuntimeLibrary.IWshShortcut shortcut = wsh.CreateShortcut(shortcutPath);
shortcut.IconLocation = String.Format("{0}, {1}", iconPath, iconIndex);
shortcut.Save();
}
Note that in order for the above code to compile, you will also need to add a reference to the Windows Script Host Object Model to your application. To do this, right-click on the "References" folder in the Solution Explorer, click the "COM" tab, and find "Windows Script Host Object Model" in the list.
I just tested this and it works; the effect is instant.

How do I debug my C# app and simulate that its running from a specfic folder?

How do I debug my C# app when it really needs to be running from a specific folder and not from bin/debug? One of the first things my program does for example is determine what set of tools will be presented based on the executable file it finds. But since its running from the debug folder it can't find them. I can add the file there but that seems silly. There has to be a better way. Plus, there's really a bunch of other thighs it does that really requires it to be running from the proper folder eg. Z:\test.
I thought it might be the "Working Directory" setting under the "Debug" tab in Properties but that didn't seem to do anything. I'm using VS2010 and C# btw...
I hope I'm making sense.
Thanks
You can specify another output folder for your build.
Try setting Environment.CurrentDirectory to the directory you want to simulate.
Environment.CurrentDirectory = #"C:\SimulateThisDirectory\";
You can use
System.IO.Directory.SetCurrentDirectory("your-path");
from your code.
You need to differ between two things:
path from which process is started
current working directory of the process
First one you can't simulate easily. It would probably involve creating a symbolic link or creating some sort of rootkit.
As for second one, your method is fine, and you can check working directory in runtime by using Directory.GetCurrentDirectory or set it using Directory.SetCurrentDirectory.
Take note that if you are looking up directory of executing assembly, you will get path from which process is started.
You can run your program from as normal from the specific directory and then just attach the debugger
http://msdn.microsoft.com/en-us/library/c6wf8e4z.aspx

Categories