I have a webapp which has read/write/execute access to an aliased directory. When I am in debug mode in Visual Studio, the following statement works:
Directory.Move("\\\\localhost\\Alias\\oldDirectory","\\\\localhost\\Alias\\newDirectory");
The net result is that, oldDirectory is now newDirectory in the aliased directory.
But, when I'm testing this code in pre-production, I have oldDirectory and newDirectory in the aliased directory. Directory.Move is now behaving as if it is only copying oldDirectory to newDirectory.
Why is this happening?
This is most likely a permissions issue.
The user account that is executing this command probably has Create / Write permissions but not Delete permissions in the aliased directory. I would check whether the user account that the program is executing under has Delete / Delete Subfolders and Files permissions.
Edit:
To test this theory, I would temporarily grant the Users group Full Control over the folder to see if the problem goes away.
Make sure the folder is not under write-protection and no process is accessing any files at the moment you are trying to move the folder.
Also check whether you gave the security permissions to the correct user, by verifing under which user account the applicationpool is running.
You might also want to consider developing on a local IIS to prevent such situations in the future (I've been there; not nice)
I believe that, instead of using Directory (which is static) I used DirectoryInfo which solved my problem. I think that the heart of the issue was that Directory does more security checks than an instance of DirectoryInfo does. I'm still unclear why this is, but it seemed to work.
Related
I'm currently running into an odd little problem in an installation wizard. On one single test VM--all the others are fine--I cannot create subdirectories in a directory I created. On the first screen I select an install location and, if it doesn't exist, create it:
c:\Program Files\Foo
Then a couple screens later, I get user credentials for the software to use and, to make sure they have the appropriate permissions, use them via impersonation to create subdirectories under Foo, say Bar and Baz. The impersonation I'm using is based on link.
The thing is, if I'm logged in as myself, that first directory is created just fine. But if I put my EXACT SAME CREDENTIALS into that later screen, it fails to create those subdirs. Despite the fact that it's the same creds that the program itself are currently running under.
Also, as I said, this works literally everywhere else except this one machine. So it doesn't make any sense. All we can figure is something broken about the impersonation system. That's all we can figure. But you'd think it would show up elsewhere. If it was something with the VM, then how did we create the Foo directory in the first place?
Anyway, any suggestions would be most welcome. This is really nutso.
EDIT: I have verified my account is local Admin on the VM. Nothing helpful in the Event viewer. Also, fixed link to MS impersonator code.
I am using Directory.Exists() in my windows service (that is programmed in C#, 3.5 framework)to check to see whether a particular directory exists in the drive. When I run in local machine it works fine, meaning I am able to access the directory.
But when I deploy the windows service on a Virtual Machine, and start the service, it is not able to find the directory even though the directory exists. The directory is mapped on as
Q: drive, Q:\\temp\\local\\ folder
But the windows services always returns false for the Directory.Exists().
However when I give C:\ drive in place of Q:\ it works, but does not work for a mapped drive. I have tried with the UNC path, and I have made sure the mapped drive have the administrative rights and infact the read, write and execute permission. But it still returns false.
Can anyone please tell me why? And how to resolve?
Make sure the drive is mapped under the same user as the Service is running. If you map the drive as user A, it is not automatically mapped for anyone else too.
Mapped drives are only restored during interactive login which services generally do not perform:
Map a network drive to be used by a service
Short version: You can't do it, use the full UNC path instead.
This is most probably a problem with privileges. Your Windows service is probably running under an account which doesn´t have enough privileges to access the network path.
This is a possible duplicate: Accessing mapped folder from a Windows Service written in C#
Another possible solution is to use impersonation, check it out:
http://msdn.microsoft.com/en-us/library/w070t6ka(v=vs.90).aspx
UPDATE
Came to think of it;
Try changing the identity of the application pool to a user with the same rights as your user.
As #Sriram pointed out the Directory.Exists() method will fail if any error occurs. What sort of exception do you get if you try to access the path?
Eg (for both mapped and UNC in case there is something going on there):
DirectoryInfo diMapped = new DirectoryInfo(#"Q:\temp\local\folder");
DirectoryInfo diUNC = new DirectoryInfo(#"\\servername\fnsw\tmp\126");
Note: Assuming that the white space before 'folder' in your path is a typo?
Steps to troubleshoot
Try accessing the network path manually in "Run" [WindowKey + R]
Try to access your map drive i.e.: M:\
Make sure you are the account owner of the mapping (mapping should be done under your account)
Go to Property and see if "Run As Administrator" is unchecked.
Remove mapping and re-add the mapping.
Make sure available offline (or sync offline) is turned off and folder is available from another computer.
Hope this helps!
I have some networkshares mounted to my PC. I can see them in the Windows Explorer, with drive letters etc. If I try to read or write with c#, I always get a DirectoryNotFoundException.
The method to check if the directory exists
Directory.Exists(#"N:\test")
returns false (N:\ is the mounted share). If I open the path in the Explorer, the path exists.
Can you imagine, what the problem could be?
Thank you!
I just tested to see if this works when I run the application as administrator and it failed. So the reason is most probably because the user under which you execute the code doesn't have access to the path.
As you confirmed that you were indeed running the application with elevated privileges, you should follow the indications that are also suggested in this answer :https://stackoverflow.com/a/11268410/674700:
(...) open an administrative command prompt - where you have an
elevated token all the time - and create a matching drive mapping from
there (net use h: \server\share1). Since the standard user and the
elevated administrator have a common understanding of what "H:" drive
means, everything runs okay.
Well, I just try to assume why you can get this exception, here it is;
First of all, Directory.Exists() method works fine for network mounted drives. There could be a few more reason that why you get DirectoryNotFoundException in your work.
From MSDN;
The Exists method returns false if any error occurs while trying to
determine if the specified file exists. This can occur in situations
that raise exceptions such as passing a file name with invalid
characters or too many characters, a failing or missing disk, or if
the caller does not have permission to read the file.
I believe you have one of this but since we can't acces your computer, we can't know the real reason :)
I ran my program in C# that suppose to create and write a file in C:\, but an error occurred saying that access to the path C:\mytextfile.txt is denied. Is there any code that will give the user permission in C:\?
Yes by using the manifest http://www.codeproject.com/Articles/66259/Requesting-Admin-Approval-at-Application-Start or run as different account which has sufficient rights
You need to run the code as an administrator. You don't need C# code for this, you need to change how you're running the code.
However, I suspect that you're trying to do something wrong. I'd guess that you're trying to store some data locally, and are using the root of C: for simplicity, when you should actually be using the standard libraries to locate the users folder or to get a temporary file.
e.g. Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
(for other folders, use Intellisense to look at the other SpecialFolder children.)
My project is a plugin to a much larger project. A bug in the larger project creates a file that will cause my application to crash. They are already aware of the issue and are addressing it, but in the meantime the only work around is to delete a certain file in the appdata directory for each user.
The plan is that during installation of the smaller plugin, to navigate to every user's appdata directory to delete a problematic file (if it exists). Is there any way to find each User's appdata directory. Remember this is an install, so we will have admin privileges. Some of the things I have seen is to use
WindowsIdentity.Impersonate(IntPtr someUser)
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
Then it would just be a matter of somehow getting the IntPtr, which I am unsure how to get.
That is the best solution I have right now. So how do I get the IntPtr of each user? Or is there a better solution?
The next best that I can think of would simply be to go through all directories of C:\Users\eachUser\AppData\ and deleting the file as it exists. But then again, in XP that location would have to be C:\Documents and Settings\eachUser\Application Data\ and I would be creating operating system specific code. Suggestions?
From WindowsIdentity.Impersonate Method (IntPtr userToken):
IntPtr userToken is...
The handle of a Windows account token. This token is usually retrieved through a call to unmanaged code, such as a call to the Win32 API LogonUser function.
So, you can't do it this way unless you have all the usernames and passwords.
Edit: Why not delete the file at runtime for just the current user? Does your plugin have permission to do this?
Edit 2: You can use the installing user's directory from Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), and then use Directory.GetDirectories to find the other users that have a profile. Then, you can tack on the special folder name. Pretty round-about, but it might work in your "pinch".