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.
Related
I want to read file names of pdfs from a folder on a network share that match certain parameters and provide a link to view them on a details page for my model. All I need to get is the file name. I don't need any file management/read/write at this time.
I'm able to display a .pdf in the browser if I have the path (IE will open "file://" links). The part I'm missing is getting file names from the remote (but same domain) directory at run-time.
We've set up a virtual directory for the app to use and that has worked fine in the past if the resolved physical folder is on the same server, but that is not the case here.
I've tried Impersonation, but that doesn't seem to work as I'm still getting an access is denied error.
I realize this would probably be a security issue and is why it isn't allowed, but is there an IIS configuration or other avenue that needs to be set-up to allow this? I can't seem to find a way with just code that opens the directory for reading.
Example code of how I might normally read some info from one file in a virtual directory:
// This example code is inside a controller action, so Server refers to HttpContextBase
var path = Server.MapPath("~/MyVirtualDirectory/" + fileName);
var fileExists = System.IO.File.Exists(path);
var fileLastModified = System.IO.File.LastWriteTime(path);
To enumerate over matching files in a directory, I've used DirectoryInfo
var pdfFileNames = new List<string>();
var dir = new DirectoryInfo(Server.MapPath("~/VirtualDirectory/"));
var pdfs = dir.EnumerateFiles("*.pdf");
foreach (var pdf in pdfs)
{
pdfFileNames.Add(pdf.Name);
}
As I mentioned, these methods work fine when the physical folder is on the same server, but once the directory is on a remote drive, then it no longer works. I have permissions to open the desired directory and my collegue said he gave the appropriate permissions to the virtual directory and server. Not sure what else to try at this point.
Edit: Now that it is working, I display the files using the Virtual Directory
http://server/appName/virtualDirectory/pdfFileName
By default, IIS application pools run under a specific local Windows identity named IIS APPPOOL\[NameOfYourAppPool]. This is a local user and it will not be possible to grant permissions to this identity to access resources located on a different machine.
If both servers are inside the same domain, you can try the following solutions:
Run the IIS application under a domain user and grant the required permissions to this domain user.
Run the IIS application under the NetworkService identity and grant permissions to the DOMAIN\MACHINENAME$ account of the IIS server.
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%.
I have a HTML file in C:\Users\myusername\AppData\Roaming\myapp\file.html. I am accessing the file through a web Browser in my C# application to preview it from within the app.
However, when the app is put onto another computer, the address in webBrowser1 is still specific to my username, and therefore other people cannot access the preview.
Is there a way to get to the file as a URL in my web Browser without having the hard coded username in the URL?
What I have tried:
C:\Users\%USERNAME%\AppData\Roaming\myapp\file.html
C:\Users\AppData\Roaming\myapp\file.html
Thanks!
Here is the code I used after I was helped:
string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string address = Path.Combine(folderPath + #"\myapp\file.html");
webBrowser1.Navigate(address);
If you want to get the name of the current logged in user you have to read Environment.UserName property.
Moreover if you need to access the AppData directory for the roaming user you can get the folder path without hard-coding anything (do not forget that users directory isn't always c:\users on every Windows version and path for AppData may vary too):
string folderPath = Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData);
In you case simply append the file name:
string url = Path.Combine(folderPath, "file.htm");
Notes
If, for any reason, you need to use environment variables then you have first to expand them:
string path = Environment.ExpandEnvironmentVariables(#"C:\Users\%USERNAME%\");
Have a look at this function. It returns the path of Current User's Application Data Folder.
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
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))
How do I search a sub directory in my ASP.Net web site?
I know if this was a regular Winform project, I could easily get it by the following:
Environment.CurrentDirectory
or
System.IO.Directory.GetCurrentDirectory()
then
string[] directories = System.IO.Path.Combine(Environment.CurrentDirectory, "Portfolio")
How do I build the path to a subfolder called Portfolio in ASP.Net?
I'm having a problem building everything from the http://??????????/Portfolio. How do I find the ?????? part?
I tried the code above but got a completely different directory...
I don't want to hard code everything before that last subfolder because it will be different on another server.
Calling Directory.GetCurrentDirectory() can be misleading when calling it from an ASP.NET app. The best way to do get around this is to use Server.MapPath() instead, which will allow you to map a web folder to its location on disk.
So for example, running this code:
string path = Server.MapPath("~/Portfolio");
will set 'path' equal to the location of that folder on disk.
If you're running this code from outside the context of a Page or control class, you won't be able to access the Server object directly. In this case, your code would look like this:
string path = HttpContext.Current.Server.MapPath("~/Portfolio");
If I understand you right, you can just access it with:
"/portfolio"
The system will concatenate "/portfolio" to the url, if, for example it is "http://site.com" you will get "http://site.com/portfolio"
If you want the physical path, you can use
server.mappath("/portfolio")
and it will return the physical directory associated (for example E:\websites\site\portfolio")
the following piece of lines gets you to the 'bin' directory
Assembly asm = Assembly.GetExecutingAssembly();
String strAppHome = Path.GetDirectoryName(asm.CodeBase).Replace("file:\\", "");