public bool FileExists(string localFilepath) { /* IMPORTANT * BEFORE CHANGING OR REFACTORING THIS METHOD, YOU MUST READ THIS NOTICE. * * The code below sounds confusing, but there is a reason to be like that. * The first issue is that the System.IO.File.Exists and Directory.Exists behavior (see Remarks Session in http://msdn.microsoft.com/en-us/library/system.io.file.exists.aspx). * If an error such as "Acess Denied" or "Invalid Path" occurs during those methods calling, * .NET API will return FALSE instead of throwing an exception. Thus, when the return is false, * maybe the file or directory exists, but some error occurred. * The best way to find out if a file or directory exists is trying to open them. The methods * that open a file (or directory) will throw an exception if it does not exist. * * Now, we have a second issue: * To do the above, it is necessary that the administrative share on the remote machine is enabled. * It´s very common that is not enabled. * The solution to this issue is to make another attempt in order to check file (or directory) existence. * You can make that through a WMI query. * * So, we have three ways to check File Existence. Why not use only WMI ? * Because, we have a third issue: performance. * In some scenarios, this WMI Query can be really slow. * OK, but why the code below still using File.Exists and Directory.Exists methods? * When those methods return TRUE, we can safely say that file (or directory) really exists. * Besides, those methods are very fast. Hence, we can stop the method if one of those methods return TRUE. */ try { var windowsConnectionProvider = new StraightNetworkConnectionProvider(); var adminShareFilePath = GetAdministrativeSharePathFromLocalFilepath(TargetInfo.GetAddress(), localFilepath); try { // To use Administrative Share resource, we need open a straight connection to remote machine. windowsConnectionProvider.Connect(TargetInfo); try { // If one of these methods return TRUE, we can return this result. if (System.IO.File.Exists(adminShareFilePath) || System.IO.Directory.Exists(adminShareFilePath)) return true; // If both methods above return FALSE, we CAN NOT rely on in this. try { // So, we will try to open the file... System.IO.File.Open(adminShareFilePath, FileMode.Open); // If we could open it, the file exists. return true; } catch (FileNotFoundException) { // obviously we can return FALSE if File.Open thrown FileNotFoundException. return false; } } catch (Exception) { try { // If any else Exception was thrown, maybe the passed path is a directory... // So, we will try to open it. System.IO.Directory.EnumerateFiles(adminShareFilePath, "*"); return true; } catch(FileNotFoundException) { return false; } } } finally { windowsConnectionProvider.Disconnect(); } } catch (Exception) { // At last, if it was not possible to check file (or directory) existence due to any error, // we will try to find this information out through WMI. var wmiParametersForFileSearching = this.CreateWmiParameters(localFilepath); var wqlForFileSearching = new WQLBuilder().WithWmiClass("CIM_LogicalFile").AddParameters(wmiParametersForFileSearching).Build(); var wmiQueryResult = this.WmiDataProvider.ExecuteWQL(wqlForFileSearching); return ((wmiQueryResult != null) && (wmiQueryResult.Count() > 0)); } }
public bool FileExists(string localFilepath) { /* IMPORTANT * BEFORE CHANGING OR REFACTORING THIS METHOD, YOU MUST READ THIS NOTICE. * * The code below sounds confusing, but there is a reason to be like that. * The first issue is that the System.IO.File.Exists and Directory.Exists behavior (see Remarks Session in http://msdn.microsoft.com/en-us/library/system.io.file.exists.aspx). * If an error such as "Acess Denied" or "Invalid Path" occurs during those methods calling, * .NET API will return FALSE instead of throwing an exception. Thus, when the return is false, * maybe the file or directory exists, but some error occurred. * The best way to find out if a file or directory exists is trying to open them. The methods * that open a file (or directory) will throw an exception if it does not exist. * * Now, we have a second issue: * To do the above, it is necessary that the administrative share on the remote machine is enabled. * It´s very common that is not enabled. * The solution to this issue is to make another attempt in order to check file (or directory) existence. * You can make that through a WMI query. * * So, we have three ways to check File Existence. Why not use only WMI ? * Because, we have a third issue: performance. * In some scenarios, this WMI Query can be really slow. * OK, but why the code below still using File.Exists and Directory.Exists methods? * When those methods return TRUE, we can safely say that file (or directory) really exists. * Besides, those methods are very fast. Hence, we can stop the method if one of those methods return TRUE. */ try { var windowsConnectionProvider = new StraightNetworkConnectionProvider(); var adminShareFilePath = GetAdministrativeSharePathFromLocalFilepath(TargetInfo.GetAddress(), localFilepath); try { // To use Administrative Share resource, we need open a straight connection to remote machine. windowsConnectionProvider.Connect(TargetInfo); try { // If one of these methods return TRUE, we can return this result. if (System.IO.File.Exists(adminShareFilePath) || System.IO.Directory.Exists(adminShareFilePath)) { return(true); } // If both methods above return FALSE, we CAN NOT rely on in this. try { // So, we will try to open the file... System.IO.File.Open(adminShareFilePath, FileMode.Open); // If we could open it, the file exists. return(true); } catch (FileNotFoundException) { // obviously we can return FALSE if File.Open thrown FileNotFoundException. return(false); } } catch (Exception) { try { // If any else Exception was thrown, maybe the passed path is a directory... // So, we will try to open it. System.IO.Directory.EnumerateFiles(adminShareFilePath, "*"); return(true); } catch (FileNotFoundException) { return(false); } } } finally { windowsConnectionProvider.Disconnect(); } } catch (Exception) { // At last, if it was not possible to check file (or directory) existence due to any error, // we will try to find this information out through WMI. var wmiParametersForFileSearching = this.CreateWmiParameters(localFilepath); var wqlForFileSearching = new WQLBuilder().WithWmiClass("CIM_LogicalFile").AddParameters(wmiParametersForFileSearching).Build(); var wmiQueryResult = this.WmiDataProvider.ExecuteWQL(wqlForFileSearching); return((wmiQueryResult != null) && (wmiQueryResult.Count() > 0)); } }