part of a console application I have is built to delete an unwanted order file out of a directory on a server we use. This part of the code works fine when I run it off of my local machine, but when we run it on the server it self (it will be a scheduled task), it no longer deletes the file.
try
{
System.IO.File.Delete(#"\\ServerName\ProductionFileShare\Orderfiles\FileDir\" + fileName);
}
catch (System.IO.IOException e)
{
Console.WriteLine(e.Message);
return;
}
The filename is just the storeorder.txt.
As I said, this works just fine on my local computer, but does not delete the file when we run this program from the server itself. Any ideas?
UPDATE: The exception message is: The process cannot access the file '\ServerName\ProductionFileShare\Orderfiles\FileDir\storeorder_07062014_16-25-0.txt' because it is being used by another process.
This is strange to me, since it works on my computer. I will add some garbage collection and see what happens.
UPDATE #2: Apparently that fixed it! That was an unexpected solution. Thanks to everyone for taking the time to comment, I really appreciate it.
I've had this problem before, where I simply moved to the admin share (\\server\c$\path\file.txt), or changed the path to a local path, and all was good.
It should be mentioned that there are both file permissions, and permissions to access the share itself, the later is likely where the problem lies.
If changing the path helps (and you do not have easy access to fix the share), then you could make it a configuration setting, and use a different configuration at each location.
Related
I know this has been asked before many times, but I have browsed tens of similar questions without help.
This error is showed when my asp.net 4.0 application tries to access a folder on my local drive, doing this:
XmlTextReader confReader = new XmlTextReader (filename);
while (confReader.Read()) // <- error line
{
// do something
}
In my web.config I have <Identity Impersonate="true">. For the folder I have assigned full-access to:
everyone
IIS APPPOOL\<custom apppoolname>
NETWORK SERVICE
Debugging the application, I can put up a watch which evaluates this call right before the incriminated line:
System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString();
the call shows the current user is IIS APPPOOL\<custom apppoolname>.
I'm on Windows 7 64bit with Sp1. I know it's probably something stupid but I have already spent an awful amount of time on this.
Edit:
The problem was in the variable "filename", which pointed to the right folder, but for a configuration problem the filename was missing (i.e. the content was "c:\data\" instead of "c:\data\file.xml"). The Asp.net error was actually confusing, since I had all the right permissions to access that folder. DJKRAZE pointed me to the right direction.
Here is what I would suggest checking
where are you declaring filename..?
Does the file even exist..?
do you have rights to that folder..? have you tried running VS as Admin..? do you have Virtual Directory setup for the web app..sounds like you have a few things configured improperly as well but can't really tell based on the code for starters this line System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString();
should yield your domain\\username or compuername\\username
Glad that FileName was all it was
IIS requires the path to a folder in the server machine has rights for Anonymous user login to access.
Make sure the user Anonymous has the rights to access the folder.
I have a job that needs to connect to two fileshares and copy some files for a data feed.
The source server is on our domain's network, and that works fine. The remote server, however, chokes on me and throws a "Could not find part of the path" error. I should add the destination server lives in a different domain than my source server.
The source and destination paths are read out of my app.config file.
I thought persistently mapping a drive would work, but since this is a scheduled task, that doesn't seem to work. I thought about using NET USE, but that doesn't seem to like taking a username and password.
The really weird thing - if I double click on the job while I'm logged into the machine, it'll run successfully.
Sample code:
DirectoryInfo di = new DirectoryInfo(srcPath);
try
{
FileInfo[] files = di.GetFiles();
foreach (FileInfo fi in files)
{
if(!(fi.Name.Contains("_desc")))
{
Console.WriteLine(fi.Name + System.Environment.NewLine);
File.Copy(fi.FullName, destPath + fi.Name, true);
fi.Delete();
}
}
}
Apparently this isn't as simple as copying the files over. Any suggestions on mapping a drive with credentials in C# 4.0?
EDIT
I'm trying to use a batch file called from the console application that maps the drive while the program is running. I'll know for sure whether that works in the morning.
I'd suggest looking into a proper file transfer protocol, like FTP.
Assuming that's out of the question, try using a UNC path like \\servername\path\file.txt. You will still need credentials, but assuming that the account running the application has those permissions you should be fine. Given that you mention a web.config file, I am guessing that would be an ASP.NET application, and therefore I mean the account that runs the Application Pool in IIS. See http://learn.iis.net/page.aspx/624/application-pool-identities/
What I finally wound up doing was mapping the drive in a batch file called by my program. I just launch a NET USE command and pause for a few seconds for the mapping to complete.
It looks like while the user is logged out, there's no context around mapped drives.
I have a program that fetches a file from a server and downloads it. It is itself located on the server, so to run it you open your browser and type in a URL with parameters.
Now, it runs perfectly fine when the program is located on my machine. However when accessed via your browser it seems to hang. I have tried
MessageBox.Show(username, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification);
string[] lines = {"First line", "Second line", "Third line"};
System.IO.File.WriteAllLines(#"C:\Users\Public\TestFolder\WriteLines.txt", lines);
and both of those cause errors when done on the server (but it's fine when on my own machine).
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\Users\Public\TestFolder\WriteLines2.txt"))
file.WriteLine("asfsd");
this seems to hang on the writeline, as the file is created but no content is ever put into the file. Any idea why this is happening or suggestions of things I can put so I know where the problem is?
If I had to guess. Id say you didnt have permissions. Try wrapping everything in an Impersonate statement or give the worker process access to the directory.
using (new Impersonator(username, domain,password)) {
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\Users\Public\TestFolder\WriteLines2.txt"))
file.WriteLine("asfsd");
}
}
Also, make sure the directory exists before writing.
It sounds like you're mixing WinForms development with ASP.NET development, and they are two very different animals.
If you are having an issue writing to a file, it's more than likely caused by a permissions issue. IIS default app pool typically runs as NETWORK SERVICE user, which most likely doesn't have permissions in your target directory.
You're trying to write to a local file and IIS on the server obviously doesn't have permissions to do that (what a surprise :-) ). Save files in your webapp folder instead, not in C:\
I know there is a ton of stuff on this already and have tried a few things but have had no luck in fixing it.
I have a C# program that has built an XML Document and im trying to save it to a folder thats in MyDocuments. I am getting the folliwing exception when calling the XMLDoc.Save function.
Access to the path 'C:\Users\Ash\Documents\ConfigOutput' is denied
I have visual studio running as administrator. Any thoughts on how to fix it?
I have tried saving onto the desktop and into the C:\ folder aswell.
I am using windows 7.
Running the built executable also doesnt seem to work.
Apologies guys it seems I was being stupid. I had indeed not added a filename to the output path. I'll not delete the question incase anyone else gets done by this gotcha! Thanks for all the help/comments.
There are a few possibilities:
ConfigOutput is a folder
ConfigOutput is a file that is in use (opened)
You're not logged in as User 'Ash'
You should not normally have to run as Admin to write to your own Documents folder.
You need to check and get permission to that directory/file your writing.. for that
use Security namesapce
var permissionSet = new PermissionSet(PermissionState.None);
var writePermission = new FileIOPermission(FileIOPermissionAccess.Write, pathToFolder);
permissionSet.AddPermission(writePermission);
if (permissionSet.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet))
{
// do your stuff
}
else
{
// alternative stuff
}
It looks like you're not specifying a filename and therefore it can't create a file with the same name as an existing directory - so try changing your path to:
C:\Users\Ash\Documents\ConfigOutput\Out.xml
Try run your app as administrator.
If you want to debug your app, start your Visual Studio as administrator also.
To force app start as administrator take a look at this thread:
How do I force my .NET application to run as administrator?
P.S. Check if your file is not already opened by another FileStream or etc.
I don't know if this makes a difference, but you may want to specify the folder in a relative rather than absolute manner: Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) will provide you with the path of the current user's documents. Check if it's different from the one you provide.
If so, you may need to run the app under a different user or administrator as others have pointed out. Obviously one user isn't allowed to just save files into another user's documents folder.
For me when I debug my app from Visual Studio the documents folder is the same as the user I'm currently logged in as and running Visual Studio under.
You could try <requestedExecutionLevel
level="asInvoker"
uiAccess="true|false"/> first and progressively move to highestAvailable and requireAdministrator.
Alternatively, demand the permissions, catch the exception and print it out:
try {
FileIOPermission fileIOPermission = new FileIOPermission(FileIOPermissionAccess.AllAccess, myDocFolderFile);
fileIOPermission.Demand();
} catch (SecurityException se) {
Debug.WriteLine(se.ToString());
}
I have a C# application, and I need to dump some output to a log file during operation. I am wanting to give the user the option of where to locate the log file, but by the client request it needs to default to the current application location, which is normally /Program Files/.
When I deploy my application on a Win7/Vista machine, though, the application does not write the log file unless I run the program as an Administrator. At the same time, it seems to be silently handling the case where it cannot write the file, as I am currently handling all exceptions being thrown during the file creation and writing process.
I am currently trying to detect lack of write permission by both:
A) Creating a DirectorySecurity object by calling "Directory.GetAccessControl()" and
B) Checking security priviledges with the "SecurityManager.IsGranted(permissions)" method,
but A does not throw an exception when I expect it to, and B returns true every time.
I have seen numerous posts related to this topic, but they all give the solution of just writing to Application.UserAppDataFolder or some variation of it. My client has specifically asked to default to the current Application path, so I need to at least find a way to gracefully warn them when writing the log file is going to silently fail.
Note: My current code works find on Windows XP (since there are no UAC, I assume). Basically all I need to know is why all my calls are telling me that writing the file is going fine, when the file is never created at all unless I am running as Admin.
Thanks!
Windows Vista and 7 will write files to the Program Files directory just fine.
Well, not really, but the program thinks it's just fine. In reality, the file is written to the current user's VirtualStore directory; that is, in %userprofile%\AppData\Local\VirtualStore\Program Files
You can include a manifest file to disable this behavior for your application to get the results you expect.
You can force the os to run your app as Admin.
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
There are three ways your app can run - elevated, deliberately not elevated (manifest saying asInvoker), or accidentally not elevated (no manifest). Elevated apps will be able to write to Program Files. Deliberately not elevated apps will get access denied. Accidentally not elevated apps will succeed but the file will be written elsewhere. This last case is what's happening to you. It didn't silently fail. You just don't know where the files are. See http://www.gregcons.com/KateBlog/FindingFilesYoureSureYouWrote.aspx for screenshots.
Therefore if the users insist on the current directory, you should add a manifest requesting asInvoker. You will then get AccessDenied and they will see the error message. I think they are odd for wanting this. Ask them if they are ok with one extra click to find them: if so, keep your app using virtualization (I really disapprove) by having no manifest and then train them to click the Compatibility Files button.
My preference: write elsewhere and manifest to asInvoker. My second choice: stick with current directory, no manifest, train them to find virtualized files. My third choice: stick with current directory, manifest to asInvoker, users see error messages when log files are not written, but logs are lost.
I am experiencing the same problem. I have an xml file that i am writing to...When I install the app(C sharp) and try to run the application am getting an exception due to write permission. When I change the file permission (give read permission to users) it is working ok..
The ultimate test for whether you have the rights to write a file is to open it for writing.
I.e.
try
{
File.Open(path, FileMode.OpenOrCreate);
...
}
catch(SecurityException)
{
... it failed for security reasons
}
catch(Exception)
{
... it failed for other reasons
}
Besides Stefan P.'s suggestion to elevate the app to run as admin, you could also modify the installation folder permission on install to to add the Users group to have write access. Then the application would work as well.
Moving the log file location would be the best option though.