Accessing Files from UNC Network Path in C# Application - c#

I have a desktop application in which the user is able to specify the input and output directories.Things work fine for local directories;but people have started complaining about network locations accessed using UNC Naming Conventions.
If the user pastes the UNC Path,the code checks if the Directory exists using the following method
if(Directory.Exists(selecteddir)
{
// all good
}
This method returns false for some network locations situated on other machines.I have tested using default local machine UNC Path \\?\C:\my_dir and the code works fine.
The application runs with administrative rights .
Im new to accessing network locations in C# Code.Is there any specific way to do this? If the user has already performed windows based authentication for the UNC Shares,wont these shares be accessible by the c# application?
Please advice on how to go forward.
Update:
I have also tried using directory info
DirectoryInfo info1 = new DirectoryInfo(#textbox.Text);
if (info1.Exists)
{
return true;
}

I have faced this situation many times. In the end, I believe that there is some issue with Directory.Exist method and I leave it.
Now, I am using DirectoryInfo class to check that like this.
DirectoryInfo info = new DirectoryInfo(#"Your Path");
if (info.Exists)
{
}
It is working fine for now. So there are other reasons too but it works for me. And of course, it does not resolve the impersonation issue.

Related

Can't see path to another server in ASP.NET MVC

I have an internal ASP.NET MVC site that needs to read an Excel file. The file is on a different server from the one that ASP.NET MVC is running on and in order to prevent access problems I'm trying to copy it to the ASP.NET MVC server.
It works OK on my dev machine but when it is deployed to the server it can't see the path.
This is the chopped down code from the model (C#):
string fPath = HttpContext.Current.Server.MapPath(#"/virtualdir");
string fName = fPath + "test.xlsm";
if (System.IO.File.Exists(fName))
{
// Copy the file and do what's necessary
}
else
{
if (!Directory.Exists(fPath))
throw new Exception($"Directory not found: {fPath} ");
else
throw new Exception($"File not found: {fName } ");
}
The error I'm getting is
Directory not found:
followed by the path.
The path in the error is correct - I've copied and pasted it into explorer and it resolves OK.
I've tried using the full UNC path, a mapped network drive and a virtual directory (as in the code above). Where required these were given network admin rights (to test only!) but still nothing has worked.
The internal website is using pass through authentication but I've used specific credentials with full admin rights for the virtual directory, and the virtual dir in IIS expands OK to the required folder.
I've also tried giving the application pool (which runs in Integrated mode) full network admin rights.
I'm kind of hoping I've just overlooked something simple and this isn't a 'security feature'.
I found this question copy files between servers asp.net mvc but the answer was to use FTP and I don't want to go down that route if I can avoid it.
Any assistance will be much appreciated.
First, To be on the safe side that your directory is building correctly, I would use the Path.Combine.
string fName = Path.Combine(fPath, "test.xlsm")
Second, I would check the following post and try some things there as it seems to be a similar issue.
Directory.Exists not working for a network path
If you are still not able to see the directory, there is a good chance the user does not have access to that network path. Likely what happened is the app pool running your application has access to the directory on the server. The production box likely doesn't have that same access. You would have to get with the network engineer to get that resolved.
Alternatively, you could write a Powershell script to run as a user who has access to both the production and the development server to copy the file over to the production server if that is your ultimate goal and your server administrators could schedule it for you if that is allowed in your environment.

File.Exists() always returns false on IIS

The file path that I'm checking with File.Exists() resides on a mapped drive (Z:\hello.txt). The code runs fine in debug environment, however in IIS, it always returns false
var fullFileName = string.Format("{0}\\{1}", ConfigurationManager.AppSettings["FileName"], fileName);
if (System.IO.File.Exists(fullFileName))
Why is this so, and how can I workaround this?
I have granted everyone full read/write permissions in that mapped drive
EDIT:
I tried deleting the file via \\192.168.1.12\Examples\Files\2.xml and I get the same result. It doesn't detect the file on IIS, but works fine on debug
I think your application do not has permission on "Z:"
Is "Z:" network disk?
I have had similar issues using network mapped drives, when running debug code application works perfectly and when running release version application cannot find the file.
If the files are stored on the same server as the application is deployed we found a solution by storing the local drive directory location of the mapped drive for example Z:\files\ could be E:\folder\folder1\
If the application is deployed on a separate server we found using the full network name works for example \\server1\folder\
I hope this proves helpful to you.
Your web application is running under a certain security context and you need to find out what context this is. If it's a normal user, open a command prompt as the user (using the runas tool), map the required drive using the command prompt (be sure to use the /persistent:yes flag)
Alternatively why can't you just use a UNC path (\\serverName\shareName) and avoid all this nonsense?
EDIT: 2013-05-27
To troubleshoot this, create a new application pool, based on whatever app pool you want. Then set the identity that this pool runs under as shown in the attached screenshot.
Make sure that this user has the correct privileges on the file share and then retest it
May be you should use Path.DirectorySeparatorChar

Why does System.IO.FileSystemWatcher crash my service when I try to monitor a folder in a network share? [duplicate]

I am trying to run a file watcher over some server path using windows service.
I am using my windows login credential to run the service, and am able to access this "someServerPath" from my login.
But when I do that from the FileSystemWatcher it throws:
The directory name \someServerPath is invalid" exception.
var fileWatcher = new FileSystemWatcher(GetServerPath())
{
NotifyFilter=(NotifyFilters.LastWrite|NotifyFilters.FileName),
EnableRaisingEvents=true,
IncludeSubdirectories=true
};
public static string GetServerPath()
{
return string.Format(#"\\{0}", FileServer1);
}
Can anyone please help me with this?
I have projects using the FileSystemWatcher object monitoring UNC paths without any issues.
My guess from looking at your code example may be that you are pointing the watcher at the root share of the server (//servername/) which may not be a valid file system share? I know it returns things like printers, scheduled tasks, etc. in windows explorer.
Try pointing the watcher to a share beneath the root - something like //servername/c$/ would be a good test example if you have remote administrative rights on the server.
With regards to the updated question, I agree that you probably need to specify a valid share, rather than just the remote server name.
[Update] Fixed previous question about the exception with this:
specify the name as #"\\someServerPath"
The \ is being escaped as a single \
When you prefix the string with an # symbol, it doesn't process the escape sequences.
I was just asked this question in regards to FileSystemWatcher code running as a service and the issue is permissions. I searched and found this question and answer but unfortunately none of the answers here solved the problem. Anyway, I just solved it, so I thought I would throw in the solution here for next guy who searches and find this question.
The drive was mapped as a logged in user but the service was running as LocalSystem. LocalSystem is a different account and does not have access to drives mapped by a user.
The fix is to either:
Authenticate first (I use a C# Class to establish a network connection with credentials)
Run your service as a user that has access to the share.
You can test LocalSystem authentication by using a LocalSystem command prompt, see How to open a command prompt running as Local System?
Even though this is already answered I thought I would put in my two cents worth becaus eyou can see this same error even if you supply valid paths.
You will get the same error when the process running the watcher does not have access to the remote share. This will happen if the watcher is in a service running under the System account and the share is created by a user. System does not have access to that share and wont recognize it, you will need to impersonate the user to get access to it.
although you can use a FileWatcher over the network, you will have to account for other factors, like disconnection of the network share. If your connection to the share is terminated (maintenance, lag, equipment reset, etc) you will no longer have a valid handle on the share in your filewatcher
You can't use directory watches over network shares, this is a limitation of the OS, not of .NET.

Copying files to a mapped drive while user is not logged in (scheduled task)

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.

FileSystemWatcher Fails to access network drive

I am trying to run a file watcher over some server path using windows service.
I am using my windows login credential to run the service, and am able to access this "someServerPath" from my login.
But when I do that from the FileSystemWatcher it throws:
The directory name \someServerPath is invalid" exception.
var fileWatcher = new FileSystemWatcher(GetServerPath())
{
NotifyFilter=(NotifyFilters.LastWrite|NotifyFilters.FileName),
EnableRaisingEvents=true,
IncludeSubdirectories=true
};
public static string GetServerPath()
{
return string.Format(#"\\{0}", FileServer1);
}
Can anyone please help me with this?
I have projects using the FileSystemWatcher object monitoring UNC paths without any issues.
My guess from looking at your code example may be that you are pointing the watcher at the root share of the server (//servername/) which may not be a valid file system share? I know it returns things like printers, scheduled tasks, etc. in windows explorer.
Try pointing the watcher to a share beneath the root - something like //servername/c$/ would be a good test example if you have remote administrative rights on the server.
With regards to the updated question, I agree that you probably need to specify a valid share, rather than just the remote server name.
[Update] Fixed previous question about the exception with this:
specify the name as #"\\someServerPath"
The \ is being escaped as a single \
When you prefix the string with an # symbol, it doesn't process the escape sequences.
I was just asked this question in regards to FileSystemWatcher code running as a service and the issue is permissions. I searched and found this question and answer but unfortunately none of the answers here solved the problem. Anyway, I just solved it, so I thought I would throw in the solution here for next guy who searches and find this question.
The drive was mapped as a logged in user but the service was running as LocalSystem. LocalSystem is a different account and does not have access to drives mapped by a user.
The fix is to either:
Authenticate first (I use a C# Class to establish a network connection with credentials)
Run your service as a user that has access to the share.
You can test LocalSystem authentication by using a LocalSystem command prompt, see How to open a command prompt running as Local System?
Even though this is already answered I thought I would put in my two cents worth becaus eyou can see this same error even if you supply valid paths.
You will get the same error when the process running the watcher does not have access to the remote share. This will happen if the watcher is in a service running under the System account and the share is created by a user. System does not have access to that share and wont recognize it, you will need to impersonate the user to get access to it.
although you can use a FileWatcher over the network, you will have to account for other factors, like disconnection of the network share. If your connection to the share is terminated (maintenance, lag, equipment reset, etc) you will no longer have a valid handle on the share in your filewatcher
You can't use directory watches over network shares, this is a limitation of the OS, not of .NET.

Categories