Notepad Path in VS2008 - c#

In my application, I have defined the following:
public static readonly string NOTEPAD = "%windir%\\notepad.exe";
I can type in the text value of NOTEPAD into the Run command on my Win7 machine, and Notepad will open.
However, from within my Visual Studio C# project, the Write Line routine will fire every time:
if (!File.Exists(NOTEPAD)) {
Console.WriteLine("File Not Found: " + NOTEPAD);
}
Does Visual Studio not understand %windir%?

Instead of expanding the variable manually as suggested by the other answers so far, you can have the Environment class do this for you just like the Run command does:
if (!File.Exists(Environment.ExpandEnvironmentVariables(NOTEPAD))) {
Console.WriteLine("File Not Found: " + NOTEPAD);
}
See http://msdn.microsoft.com/en-us/library/system.environment.expandenvironmentvariables.aspx

When looking on my windows XP box, the location of notepad is:
%SystemRoot%\system32\notepad.exe
Not:
%windir%\notepad.exe
You also need to make sure that these environment variables are resolved correctly - use Environment.GetEnvironmentVariable and Path.Combine to build up the correct path:
string root = Environment.GetEnvironmentVariable("SystemRoot");
string path = Path.Combine(root, "system32", "notepad.exe");

Just have a closer Look at the Class Environment. The Environment Variable is SystemRoot, so you can use
Environment.GetEnvironmentVariable("windir") (or something like that)
http://msdn.microsoft.com/en-us/library/system.environment.getenvironmentvariable.aspx
The console "Resolves" the %windir% environment variable to the correct path. You need to use the above function to do the same within your application.

Use Environment.GetEnvironmentVariable("windir");
So you could declare it like this:
public static readonly string NOTEPAD = Environment.GetEnvironmentVariable("windir") + "\\notepad.exe";

Related

How to run a program in the same folder?

So I'm learning how to develop software and I'm running into a problem. When I create a form in Visual Studio and have it open a document or open something else when I click a button I have it pointing here:
C:\User\MyName\Documents\TestApp\test.txt
What I want to know is how do I get it to where the program just looks at TestApp folder vs going through the C: Drive? Say all the files are needed for the program to run are located in the TestApp folder.
If you know that your app is going to be run from the same place every time (like a folder) you can call the GetCurrentDirectory() method. This will return a string of the current directory that your app is running from.
String pwd = GetCurrentDirectory(); //Contains something like C:\Users\Daedric\TestApp\
String finalString = Path.Combine(pwd, "test.txt"); //As per Corak
You need start file from your app folder?
Application.StartupPath
for start file
Process.Start(Application.StartupPath + #"\test.txt");
Besides above answer, following example can help you understand how Path works:
class Program
{
static void Main()
{
string[] pages = new string[]
{
"cat.aspx",
"really-long-page.aspx",
"test.aspx",
"invalid-page",
"something-else.aspx",
"Content/Rat.aspx",
"http://dotnetperls.com/Cat/Mouse.aspx",
"C:\\Windows\\File.txt",
"C:\\Word-2007.docx"
};
foreach (string page in pages)
{
string name = Path.GetFileName(page);
string nameKey = Path.GetFileNameWithoutExtension(page);
string directory = Path.GetDirectoryName(page);
//
// Display the Path strings we extracted.
//
Console.WriteLine("{0}, {1}, {2}, {3}",
page, name, nameKey, directory);
}
}
}
Sample output would be like this:
Input C:\Windows\File.txt
GetFileName: File.txt
GetDirectoryName: C:\Windows
GetCurrentDirectory is not the correct method to use as the return value can change while you application is running. You can see this by simply running the following in a console app:
Console.WriteLine(Directory.GetCurrentDirectory());
Directory.SetCurrentDirectory(#"c:\temp\");
Console.WriteLine(Directory.GetCurrentDirectory());
You can use the following to give you the assembly location:
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)

Environment is not being set in windows using c#. Where am I going wrong?

string path = System.Environment.GetEnvironmentVariable("Path");
Console.WriteLine(path);
if (!path.Contains("C:\ccstg"))
{
if (!path.EndsWith(";"))
path = path + ';';
var v=#"C:\ccstg;";
path = path + v;
Environment.SetEnvironmentVariable("Path",path);
Console.WriteLine(path);
Console.WriteLine("Path Set");
Console.ReadKey();
}
I am trying to set path environment variable using c#, I am able to get "Path" but while setting it is not being set. It doesn't show any error either. I have tried running it as administrator also , no help.
Does anybody what am I missing here ?
Firstly, you need to be a little more careful with your string literals, the code you posted won't compile because "\c" is not a valid string literal escape sequence. To fix:
string newPathComponent = #"C:\ccstg";
if (!path.Contains(newPathComponent))
{
if (!path.EndsWith(";"))
path = path + ';';
path = path + newPathComponent;
Environment.SetEnvironmentVariable("Path", path);
Now, this code works and sets the path for the duration of the process. If you want to set the path permanently, you need to use Environment.SetEnvironmentVariable Method (String, String, EnvironmentVariableTarget), for instance:
var target = EnvironmentVariableTarget.User; // Or EnvironmentVariableTarget.Machine
Environment.SetEnvironmentVariable("Path", path, target);
More here.
However, if you do that, you have to be careful to add your path component only to the path associated with that EnvironmentVariableTarget. That's because the %PATH% environment variable is actually combined from several sources. If you aren't careful, you may copy the combined path into just the EnvironmentVariableTarget.Machine or EnvironmentVariableTarget.User source -- which you do not want to do.
Thus:
static void AddToEnvironmentPath(string pathComponent, EnvironmentVariableTarget target)
{
string targetPath = System.Environment.GetEnvironmentVariable("Path", target) ?? string.Empty;
if (!string.IsNullOrEmpty(targetPath) && !targetPath.EndsWith(";"))
targetPath = targetPath + ';';
targetPath = targetPath + pathComponent;
Environment.SetEnvironmentVariable("Path", targetPath, target);
}
Finally, if you are running inside the Visual Studio Hosting Process for debugging, I have observed that if you use Environment.SetEnvironmentVariable("Path",path, EnvironmentVariableTarget.User), changes to the permanent environment will not be picked up until you exit and restart visual studio. Something weird to do with the visual studio hosting process, I reckon. To handle this odd scenario you might want to do both:
AddToEnvironmentPath(#"C:\ccstg", EnvironmentVariableTarget.User)
AddToEnvironmentPath(#"C:\ccstg", EnvironmentVariableTarget.Process)
SetEnvironmentVariable sets the variable for the current process. Your process has its own environment. When you set an environment variable in your program, it only affects your program's environment.
If you want to affect the user's environment, that is, make the change so that it can be seen outside your program, then you have to call this overload. For example:
Environment.SetEnvironmentVariable("Path", path, EnvironmentVariableTarget.User);
See EnvironmentVariableTarget enumeration for more details.

recognize if program was run from Desktop

Is there any way to recognize if the application has been run from a shortcut instead of executable file? I need to make my users to copy exe file to their desktops rather than create shortcuts to it due to personalization issues. Any ideas?
Edit: creating the installer is not an option.
I don't know if this helps, but if you want your exe file to be on the desktop, this could work:
string path = Directory.GetCurrentDirectory();
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
if (!path.Equals(desktopPath))
{
Console.WriteLine("file is not at desktop");
}
If you do have an app in the windows shared folder you can configure it to prevent execution of the applications.
Or you can provide user just with link to .bat file instead of .exe and it would do something like this (using robocopy):
robocopy \\remote\server\exe %AppData%\your\folder app.exe /XO
start %AppData%\your\folder\app.exe
And on the C# side you can just check application path and do something like this:
public class Program
{
public int Main()
{
string original_path = System.IO.Path.GetFullPath(#"\\remote\app.exe");
string current_path = System.IO.Path.GetFullPath(
System.Reflection.Assembly.GetExecutingAssembly().Location);
if(original_path == current_path){
System.IO.File.Copy(original_path, #"C:\foo\bar\app.exe", true);
System.Diagnostics.Process.Start(#"C:\foo\bar\app.exe");
return 0;
}
// Run program normally here
}
}

Expand environment variable for My Documents

I know I can read environment variables like this:
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
However, it would be really helpful to me if I could do something like this:
Environment.ExpandEnvironmentVariables(#"%MyDocuments%\Foo");
Is there an environement variable that equals SpecialFolder.MyDocuments?
I also tried to do something like this, but this doesn't lead to the expected result:
Environment.ExpandEnvironmentVariables(#"%USERPROFILE%\My Documents\Foo");
This way I ended up with something like #"C:\Users\<MyUser>\My Documents\Foo" but I what I need is #"\\someservername\users$\<MyUser>\My Documents\Foo".
EDIT: My Goal is NOT to hardcode either environment variable nor the part after that.
Any other suggestions?
No there is no environment variable for the MyDocuments special folder (the same is true for most members of the SpecialFolder enumeration).
Check out this snippet, it might be exactly what you are searching for.
It allows you to do something like that:
string fullPath = SpecialFolder.ExpandVariables(#"%MyDocuments%\Foo");
Note: SpecialFolder.ExpandVariables is a static method of a helper class introduced in the above snippet.
Is there an environment variable that equals SpecialFolder.MyDocuments?
Short answer: No.
Long answer:
Still no. You can type "set" into a Command Prompt to see all you current environment variables. I couldn't find any for my documents folder on my profile (tried on WinXP and Win7).
Also, expanding "%USERPROFILE%\My Documents" would be incorrect since the user's documents folder could be anywhere else (e.g., on my home PC I always change mine to D:\Documents).
If you really need to use environment variables, one solution might be to set the variable yourself:
// this environment variable is created for the current process only
string documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
Environment.SetEnvironmentVariable("MYDOCUMENTS", documents);
Another solution might be to use a "fake" environment variable in the path and expand it yourself, something like:
string path = "%MYDOCUMENTS%\\Foo"; // read from config
// expand real env. vars
string expandedPath1 = Environment.ExpandEnvironmentVariables(path);
// expand our "fake" env. var
string documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string expandedPath2 = path.Replace("%MYDOCUMENTS%", documents);
What exactly are you trying to do? Is there any reason why you can't just use Path.Combine?
string docs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string foo = Path.Combine(docs, "Foo");
I'm not sure if there is a good way to do this but instead of trying to do environment expansion to get the path why not use the Path.Combine API instead?
Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
"Foo");
You can expand environment variables using then Environment.GetEnvironmentVariable method. Given your comment, I would suggest breaking your path up into 2 separate config settings to make expanding it easier:
string variablePath = "%appdata%".Trim('%'); //read from some config setting
string appdataPath = Environment.GetEnvironmentVariable(variablePath);
string subdir = "foo"; //some other config setting
string myDir = Path.Combine(appdataPath, subdir);
No it does not exist. The easiest way to check is to run "set" from command line and see yourself.
Start-> run -> cmd
set
set |findstr /i documents

In Windows Vista and 7, I can't access the %DEFAULTUSERPROFILE% system variable - it shows as not found

If I try to access this system variable from the Run... dialog, Windows tells me the directory doesn't exist. Some system variables, like %SYSTEMROOT% and %USERPROFILE%, do work. Consequently, if I try to use a supposedly nonexistent variable like %DEFAULTUSERPROFILE% or %PROFILESFOLDER% in C#, I get nothing in return. Is there something special I need to do to get access to these variables?
Have you tried %ALLUSERSPROFILE%?
I need to point to
C:\Users\Default\AppData.
Are you sure? Be aware that this folder is used to populate the inital AppData directory for each new user added to the system.
If you want the actual shared application data directory in .NET, it's this:
String commonAppData = Environment.GetFolderPath(Environment.SpecialFolders.CommonApplicationData)
My suggestion is to retreive that value directly from the registry - in case you can't expand it:
public static string GetDefaultUserProfilePath() {
string path = System.Environment.GetEnvironmentVariable("DEFAULTUSERPROFILE") ?? string.Empty;
if (path.Length == 0) {
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList")) {
path = (string)key.GetValue("Default", string.Empty);
}
}
return path;
}
You mention C# - you can't use environment variables inside C# path strings, you need to replace them using System.Environment.
System.Environment.GetEnvironmentalVariable("USERPROFILE");
I haven't seen %DefaultUserProfile% before - should it point to the first username that was installed?
Call SHGetFolderLocation with CSIDL_PROFILE and -1 as the token parameter

Categories

Resources