I have 1 form and 1 service that should be writting to the same location.
So I added the following line in both.
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "myFolder" + Path.DirectorySeparatorChar + "log.txt");
the problem is that the form is writing the file in the right location but the service isn't. The service is writing in C:\Windows\System32\config\systemprofile\AppData\Roaming\myFolder\log.txt and the form in C:\Users\<user>\AppData\Roaming\myFolder\log.txt.
I can't use the windows event logger and i got to handle some other files too.
The user that runs the service is either NETWORK SERVICE or LOCAL SERVICE, instead of a real user account. Under those special accounts, Environment.SpecialFolder.ApplicationData comes to the systemprofile directory.
So to fix that, you'll need to change the user the service runs under, or hard code/determine the correct user directory to use.
Put the folder name in a config file. Or at least put the user's name, so you can build the folder name properly in the service.
Related
i have an application which requires access permission to a file on remote server.
My app is in Server A, and the file i want to access is in Server B. These 2 servers are in the same domain.
I created a virtual directory in Server A for the directory in Server B. The name of virtual directory is FolderFromServerB and its path is \ServerB\Folder. I use a user for auth, and when i test the connection in IIS it says all is OK.
Also, when i put an anchor tag in a test file like below, i can access the file and the content is shown in the page:
Test file --> **This works**
But my problem is when i use code in order to if that file exists or not, it always returns with False. My code is like below:
FileInfo fi = new FileInfo(#"\FolderFromServerB/test.txt"); --> This doesn't work
Response.Write(fi.Exists); --> This always 'False'
I granted 'Full Control' permission to my user& NETWORK SERVICE & Everyone & Administratos in Server B but i didnt work neither.
How can i make it work?
It was working last week. I guess the server updated itself and some updates made that occur, but i couldn't find any workaround. Im so desperate now and i have to change all of my code and spend much time to make it work.
I found the workaround that is in web.config :
<identity impersonate="true" userName="{domain}\{username}" password="{password}"/>
I used File.Exist() for a few months, but then suddenly it was gone and didnt work, and i dont know why. But it is the solution above.
Your code does not work because the current execution folder of an ASP.Net application is not the folder of you application, but c:\windows\system32.
When you create the FileInfo object, you will try to read c:\windows\system32\FolderFromServerB\test.txt.
The <a href="FolderFromServerB/test.txt"> works because the link will be relative to the current page (it won't works if the page is in another directory).
If the file you are looking for is under your application directory, you can convert a virtual to a physical path using :
string actualFilePath = HttpContext.Current.Server.MapPath("~/FolderFromServerB/test.txt");
FileInfo fi = new FileInfo(actualFilePath);
I have a code which is similar this:
string file;
using (StreamReader r = new StreamReader("xml.xml"))
{
file = r.ReadToEnd();
}
XElement xml = XElement.Parse(file);
using (XmlWriter w = XmlWriter.Create("xml.xml")) //The point of problem!
{
w.WriteStartDocument();
...;
w.WriteEndDocument();
}
When I try run it like a console application is everything all right. But problems start when I want to use it in an ASP.NET application. At the using line it throws UnauthorizedAccessException exception with a description "access to the path is denied". Why?
You need to check which account your application Pool is using to access your server files/folders, for example, make one code to copy one file to application folder, check all security info, copy and paste on this problem folder, normally use this account "IIS_IURRS" give full control to test only...
If IIS/the web server is configured correctly, an account with a very limited set of permissions is used. As your path points to the application directory, it is very likely that the application pool account is not allowed to write to this location.
If you run the code in a console application, your user's permissions are applied and it is more than likely that you are allowed to write to the output folder of the project as Visual Studio writes the build output there under your account.
I would not recommend to change the application pool account or the permissions of the application folder in the file system - it is a very sensible limitation that limits the amount of trouble an attacker can possibly make.
Therefore I'd recommend to either move the file to a folder that the account can write to without changing permissions or define a special one outside of the application folder hierarchy that the account is given permissions to.
Also keep in mind that multiple users might access the file at the same time, so a database might be a better choice to store the data.
I have built an app that works only when not run as a Windows service. Well, the service runs, but it doesn't do what it should. The service uses the Local Service account. So to kick off debugging, I thought I'd start with something simple: have it create a directory when it starts:
Directory.CreateDirectory(
Environment.SpecialFolder.LocalApplicationData + "\\MyService");
When I started the service, it stopped almost immediately and Windows reported that fact. When I commented out the above statement, recompiled and re-installed, the service ran without stopping.
Obviously the above line throws an exception of some sort. I have no way of logging the error because I can't write to the file system. Any ideas why Local Service can't create a directory in its own %LOCALAPPDATA%?
You should use GetFolderPath with LocalApplicationData like so:
string folderName = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.LocalApplicationData),
"MyService");
Directory.CreateDirectory(folderName)
I think this might be because there is no special folder. When running as the local service account you are running under that user, not the logged in user. so you are requesting a special folder that probably wont exist, as I don't think the local service has a profile. (I may be wrong) - I was wrong :p
Just in case anyone pops by:
C:\Windows\ServiceProfiles\LocalService
is the local service profile folder, so it will end up in there.
If you want to debug it surround that line with a try catch, and then write the error to a file:
try
{
Directory.CreateDirectory(Environment.SpecialFolder.LocalApplicationData + "\\MyService");
}
catch (Exception ex)
{
System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\MyServicelog.txt",true);
file.WriteLine(ex.Message);
file.Close();
}
At least then you can see whats causing the error
Martyn
I suggest you write the exception details to the event log. All user accounts have permission to write to the event log as long as the log and source names have already been created by an administrator (which you can do simply by running the app as yourself first).
As to the root cause of the error, it may be because LocalService doesn't normally get a full set of profile folders created by default. I'm not sure whether this is by design, or simply what I have observed on various machines.
In the process of writing a service I have
//# Service Account Information
serviceProcessInstaller.Account = ServiceAccount.LocalSystem;
in the installer for it.
I was having problems writing a log to
static string USERS_HOME_DIR = Environment.GetEnvironmentVariable("HOMEDRIVE") + Environment.GetEnvironmentVariable("HOMEPATH");
since when the service was running (installed "as administrator") the event logger was reporting
Service cannot be started. System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Documents\Folder of Interest'
I need the HOMEPATHs of the users of the local_PC, any ideas how to get them?
UPDATE
Actually it would be better to just get the path for the currently logged on user, as their session and the service start. My sevice is not re-entrant but one user is better than none.
If I understand your question correctly what you're looking for are the special folder enumerations.
With something like:
String PersonalFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
If you want to run the service as the localsystem account there's a separate set of standards for storing the data. See this answer on serverfault.
I have a asp.net web application that creates a Folder on a FTP site, but I need to grant permissions to that folder to some users of the active directory.
How can I do that programatically, inside my app when I create the folder?
Standard FTP does not allow for changing of permissions or file ownership, but it is reasonably common for FTP servers to allow this sort of thing through custom SITE commands. At least, this is common for UNIX hosted FTP servers.
Try connecting to the server with a standard FTP client and typing site help. That should give you a list of the custom SITE commands available. You can then get the usage for a specific command by typing site help <cmd>.
I'm not sure what your options will be against a Windows-based server, as the permissions model is more granular than with standard UNIX permissions. On a UNIX server, you can often change the group ownership and the permissions, but changing the file owner is not allowed unless you're root. I shouldn't have to say that logging into an FTP server as root is a really bad idea.
I hope that's some help.
R
You don't say what kind of FTP server you are running, or in what manner you want the AD user to interact with the new folder. I'm assuming that you are using IIS's FTP Service, and that you need your AD users to be able to use FTP to access the new folder.
IIS uses the same access rights as other file access methods in Windows (accessed from the Security tab on the folder's Properties view).
I created a WinForm that would do the following: create a new local user account (and add them to a group), create a new directory under our FTP Server's base directory, create a new Virtual FTP Folder (so that a user could map a connection to the folder), and finally give the new user full control of the new directory (and because the directory was a Virtual Folder, the new user has full control via FTP).
It sounds like you don't need to create the new user, you just need to give them permission to make changes to the new directory. In my app I shell out to invoke a batch file and pass it a few parameter.
The command for modifying a directory (or file's) access rights is:
cacls [The path to your new directory] /E /P [The AD user name]:C
I don't recall what those parameters mean any more; I suggest you research the command to make sure it does exactly what you want.
To execute this from VB.Net:
Shell(System.Configuration.ConfigurationSettings.AppSettings.Item("CACLS_batPath") & " " & strFolderPath & " " & _strUserName, AppWinStyle.NormalFocus, True, -1)
That will open a visible command window and execute the batch file, passing it the parameters. (It just occured to me that I'm doing this in WinForms and it might not be that easy to call from ASP.Net, check here for information about executing a batch file from ASP.Net: http://codebetter.com/blogs/brendan.tompkins/archive/2004/05/13/13484.aspx)
The contents of the BAT file are:
echo "update file permissions"
cacls %1 /E /P %2:C
REM PAUSE
Good Luck!
I'm assuming that you are creating the folder and want to set the permissions in a c# application.
You want to look at the DirectorySecurity class (msdn)
You create a directorySecurity class for the newly created directory and then you add FileSystemAccessRules to define the appropriate access based on AD users and groups.