I need to detect if my application is being executed from the users directory.
For example c:/users on Windows7.
But i need it to work on all Windows versions.
You can get the directory of the current application as follows:
string appPath = Path.GetDirectoryName(Application.ExecutablePath);
You then need a string compare to see to check if the path startswith:
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
Or which ever location you want to test against, see here for list os special folders. These resolve appropriately under each OS version.
bool isUsersPath = System.Reflection.Assembly.GetExecutingAssembly().Location.StartsWith(System.Environment.GetFolderPath(Environment.SpecialFolder.UserProfile))
Related
I have deployed a .NET Core webapplication on a Ubuntu 16.04 LTS server using nginx.
I'd like to find this directory:
# Location source code
/home/user-0123456/webapp
From within this location:
// Location compiled code and source to outside world
/var/webapp
In this situation, user-0123456 is fixed, but the fix should be generic. So i.e., it could be different in the future - but you can assume there will always be one user.
I did came across this post, but both these lines:
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)
Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)
return /var/www instead of /home/user-0123456/webapp.
Question
So how can I find the root directory of my 'webapp'-dir in the home folder from inside another path?
Simple, you can get the HOME directory with:
System.Environment.GetEnvironmentVariable("HOME");
However, if your application runs under the account www-data, "home" will be the home-directory of the user www-data, and not the user you are currently logged in...
And if you want to get the root-directory of the web-application, that would be
System.IO.Path.GetDirectoryName(typeof(Program).Assembly.Location);
But if you want to map the directory in /var/xyz to /home/user-123/xyz, then you do:
string user = System.Environment.GetEnvironmentVariable("USER");
string app = System.IO.Path.GetDirectoryName(typeof(Program).Assembly.Location);
app = app.Substring("/var/".Length);
string sourceDir = System.IO.Path.Combine("/home", user, app);
If you actually need the home directory of another user, this is how you get it by user-name:
string username = "user-123";
Mono.Unix.Native.Passwd pwd = Mono.Unix.Native.Syscall.getpwnam(username);
// pwd.pw_uid
string dir = pwd.pw_dir;
System.Console.WriteLine((dir));
The last one requires Mono.Posix compiled for .NET-Core/NetStandard2.0 and the native library that mono.posix wraps its Linux-syscalls around.
I have a Windows From application that runs several things on voice commands.
On a certain command I want to start Spotify, as you may know Spotify is installed in C:\\Users\\Danny\\AppData\\Roaming\\Spotify\\Spotify.exe.
This isn't a problem as long as my application is installed on my own PC. But when I want to run my app on different PC's this of course won't work.
Is there a way to maybe use a generic path to run this application?
Use the Envoirment.SpecialFolder.
If you use the Environment.SpecialFolder than it will get a path for the current user, so you don't have to type the path manually:
This example will get the path for the appdata folder. From there you can go further into the file structure, like I did with the Path.Comine() to prevent any path combine errors.
// Get appdata folder path for every user
string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
// Your extension to Spotify.exe
string extentionToPath = "Spotify\\Spotify.exe";
// Finalpath, combine the appdata with your own extention.
string finalPath = Path.Combine(appDataPath, extentionToPath);
// one line to get the path
string finalPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "\\Roaming\\Spotify\\Spotify.exe");
So now as you can start the process by doing this:
Process.Start(finalPath);
Is there a way to set my app.config for my WCF service so that it outputs to the LocalApplicationData folder without having to hardcode anything?
%LOCALAPPDATA% does not work in XP, and I need to support XP
I have found that shell:Local AppData works, but I am not sure how to put this in an app.config
The next closest I can find is %APPDATA%, but I do not believe this is not the same as LocalApplicationData
Worst case, I can (but would prefer not to) use code to do this (using the SpecialFolders directly), but I am not sure how to set this while keeping the rest of the settings configurable?
You can get it from Environment object.
string path;
path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
Edit according to comment:
Now i understand. You can create your own environment variables to use as part of path in your config.
CMD:
set mylocalapplicationdata="somewhere"
or C#:
string name = "mylocalapplicationdata";
string value = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
Environment.SetEnvironmentVariable(name, value);
After this you can use %mylocalapplicationdata% like other system variables.
You can set variable for one session (process), user, or machine (for machine you need admin permissions).
More information (MSDN):
http://msdn.microsoft.com/en-us/library/z46c489x.aspx
Alternatively you can use string like this:
%USERPROFILE%\Local Settings\Application Data
but this is for windows xp only.
I don't think there's a way to get the information you want using only built-in environment variables. The information is inconsistent from Windows XP to Windows Vista/7, so I think your best option is to update your config file during installation where you can determine the OS and access other Windows APIs.
I have created a .msi by using VS2008 setup project. My application frequently writes some value in a .txt file in the application directory (C:\Program Files\MyApp\MyFile.txt). After insalling it in Win7, it raises an exception "Access to the path .... is denied."
But whenever I run it as administrator, no such exception occurs. Here is my sscce
string FilePath=Application.StartupPath + #"\AppSettings\CurrentUserName.inf";
using (StreamWriter writer=new StreamWriter(FilePath,false))
{
writer.Write(txtLoginName.Text.Trim());
}
MainForm.ProcessLogIn();
this.DialogResult = DialogResult.OK;
I don't know how to solve this problem. Any suggestion?
Move your file out of Program Files directory. In Win7 is readonly for normal users.
You could move the file in the ProgramData directory.
Your installer should create a directory for your application there.
Then inside your code you could retrieve the correct full pathname using these lines of code
string dataPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData));
string appFile = Path.Combine(dataPath, "MyAppDir", "MyFile.txt");
usually (on Win7) this result in a path like this
c:\programdata\MyAppDir\MyFile.txt
but using the SpecialFolder enum you are guaranteed to use a folder available in readwrite to your application not depending on the current operating system.
The only way to solve this problem is to not write to that folder. You are not allowed to write to that folder by convention, unfortunately, older versions of Windows did not hold you to this.
Instead, you can use Environment.SpecialFolder to help you find where you need to go:
// your application data for just that User running the app
var perUserAppData = Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData);
// your application data for ALL users running the app
var allUsersAppData = Environment.GetFolderPath(
Environment.SpecialFolder.CommonApplicationData);
// better!
var path = Path.Combine(perUserAppData, #"MyApp\MyFile.txt");
Basically, Windows 7 is telling you that you're going to have to stop driving on the sidewalks and use the street as was intended.
As a short-term fix, you can use ICACLS to grant write access to the file. Note: NOT the whole directory.
As a longer term fix, you should NOT write to the program directory if you are running as unprivileged users, but instead somewhere like %LOCALAPPDATA% or %APPDATA%.
What I am trying to do is read data from a CSV file located within a Windows application folder named "Attachments". In a web application you can get the path of the folder using
Server.MapPath(#"Attachments/sample.csv");
What is the equivalent call from a Windows application?
Below is my code.
string[] str = File.ReadAllLines(#"Attachment/sample.csv");
// create new datatable
DataTable dt = new DataTable();
// get the column header means first line
string[] temp = str[0].Split(';');
// creates columns of gridview as per the header name
foreach (string t in temp)
{
dt.Columns.Add(t, typeof(string));
}
Is the path relative to the executable? If so you can use Application.StartupPath to determine where the program was started, and then combine that with the relative file path to get the full path:
var fullPath = Path.Combine(Application.StartupPath, #"Attachment\sample.csv");
If your app is running as a service or uses ClickOnce deployment this won't work, though.
The Windows Application Folder could be identified by this enum
Environment.SpecialFolder.ProgramFiles
MSDN refs
To get a string containing the actual path and the full file name you write
string pathToFile = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
string fullFileName = Path.Combine(pathToFile, #"Attachment\sample.csv");
As noted by Cole Johnson in its comment, there is a problem if your hosting operating system is 64bit. In that case there are two application folders. One for 64bit apps and one for 32bit apps.
Using NET4, you could discover the current operating system bitness with the property
Environment.Is64BitOperatingSystem
and, if false, use a different enum
Environment.SpecialFolder.ProgramFilesX86
But after all this, I think you should change something in the architecture of your program.
In Web applications, usually you do not use folders outside the web-root.
But WinForms application has no such limitation and then you may install the CSV files in a different folder (MyDocuments comes to mind) and control the actual location on your hard disk via an option in the configuration file
REMEMBER: The Application Folder requires particular permission to write in (If you save your attachments there this is another reason to choose a different location than the Application Folder)
You can do this with So something like
Path.Combine(Application.StartupPath, #"Attachment\sample.csv");
Steve beat me to it but yeah, check intellisense for whatever folder you're looking for under :
string path = Environment.GetFolderPath(Environment.SpecialFolder.
properties
You'll find all kinds of system paths there.