How to invoke PathTooLongException?

415 views Asked by At

I have a small utility that keeps hitting PathTooLongException and I was instructed to output the file path for the error, with is fine... somewhat.

However I find myself not able to replicate the issue. I tried creating a file with a path that is bigger than the MAX_PATH, but my program handles it fine. I tried to increase the path size even more but Windows did not allow for this, and the kicker is that through CMD can't even go to the containing folder because I do hit PathTooLongException before that, yet my program handles it just fine, no exception thrown.

What's really weird is that although the exception is never thrown, the program simply ignores the file in question, this is the peace of code that can't seam to find it and does not throw an error.

string fileName;
DirectoryInfo di = new DirectoryInfo(strFolderPath);
IEnumerable<FileInfo> fileList = di.EnumerateFiles("*", SearchOption.AllDirectories);
foreach (FileInfo fi in fileList)
{
    fileName = fi.FullName.Remove(0, di.FullName.Length + 1);
}

I find myself in a weird situation, with no way to invoke the error, I am supposed to handle.

PS. I think I should mention that I can't use the deployment paths, because of various reasons.

Here is the full path, in theory:
C:\net\sync-test-1\G1244kljsdfglksdjflsdjlfkjajhalsjflkdsajkljsdflk\long_name_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItI\long_na.txt

Here is the same containing folder when I take it from windows address bar: C:\net\SYNC-T~1\G1244K~1\long_name_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItIs_YesItI

And this is the stack trace that the program sent out in deployment:

System.IO.PathTooLongException: The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
   at System.IO.PathHelper.GetFullPathName()
   at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
   at System.Security.Util.StringExpressionSet.CanonicalizePath(String path, Boolean needFullPath)
   at System.Security.Util.StringExpressionSet.CreateListFromExpressions(String[] str, Boolean needFullPath)
   at System.Security.Permissions.FileIOPermission.AddPathList(FileIOPermissionAccess access, AccessControlActions control, String[] pathListOrig, Boolean checkForDuplicates, Boolean needFullPath, Boolean copyPathList)
   at System.IO.FileSystemInfo.get_FullName()
   at Neudesic.BlobDrop.BlobDrop.SyncContainer(BlobTask task)

So here is the source code for the SyncContainer():

// Sync local folder to container
private bool SyncContainer(BlobTask task)
{
    try
    {
        List<CloudBlob> blobList;
        Dictionary<string, CloudBlob> blobDict = new Dictionary<string,CloudBlob>();

        // Enumerate blobs in container.

        if (BlobHelper.ListBlobs(Container, out blobList))
        {
            // Put blob in a dictionary so we can easily look it up by name.
            foreach (CloudBlob blob in blobList)
            {
                blobDict.Add(blob.Name, blob);
            }

            // Enumerate the files in the watch folder - upload any files that do not yet have corresponding blobs in storage.
            string fileName;
            DirectoryInfo di = new DirectoryInfo(FolderPath);
            IEnumerable<FileInfo> fileList = di.EnumerateFiles("*", SearchOption.AllDirectories);
            foreach (FileInfo fi in fileList)
            {
                fileName = fi.FullName.Remove(0, di.FullName.Length + 1);
                if (!isPathSafe(fi.FullName))
                    continue;

                if (BlobHelper.doesTheBlobExist(fileName, Container))
                {
                    Info("  [" + Container + "\\" + fileName + "]: already in blob storage");
                }
                else
                {
                    Warning("  [" + Container + "\\" + fileName + "]: not found, adding upload task");

                    BlobQueue.Add(new BlobTask()
                    {
                        Action = "upload",
                        BlobName = fileName,
                        ContainerName = Container,
                        FilePath = fi.FullName,
                        RemainingRetryCount = MAX_RETRY_COUNT
                    });
                }
            }


            //checks the blob for all exess files in the blob and then removes them
            CloudBlobContainer container = BlobHelper.BlobClient.GetContainerReference(Container);
            BlobRequestOptions options = new BlobRequestOptions();
            options.UseFlatBlobListing = true;
            IEnumerable<IListBlobItem> blobs = container.ListBlobs(options);
            CloudBlob cbBlob;
            string mimeType;

            if (blobs.Count() > 0)
            {
                int containerLength = container.Name.Length + 2;
                foreach (IListBlobItem blob in blobs)
                {
                    if (blob is CloudBlob)
                    {
                        cbBlob = blob as CloudBlob;
                        fileName = cbBlob.Name;
                        string filePath = String.Concat(di.FullName, '\\', fileName);

                        mimeType = BlobHelper.getFileMimeTypeFromPath(filePath);
                        cbBlob.FetchAttributes();
                        // set cache-control header if necessary
                        if (cbBlob.Properties.CacheControl != BlobHelper.blobCacheHeader)
                        {
                            cbBlob.Properties.CacheControl = BlobHelper.blobCacheHeader;
                        }
                        if (cbBlob.Properties.ContentType != mimeType)
                        {
                            cbBlob.Properties.ContentType = mimeType;
                        }
                        cbBlob.SetProperties();

                        if (!File.Exists(filePath) || !isPathSafe(filePath))
                        {
                            Warning("  [" + Container + "\\" + fileName + "]: not found in system, but found in blob, adding deletion task");

                            BlobQueue.Add(new BlobTask()
                            {
                                Action = "delete",
                                BlobName = fileName,
                                ContainerName = Container,
                                FilePath = filePath
                            });
                        }
                    }
                }
            }

            return true;
        }
        return false;
    }
    catch (Exception ex)
    {
        if (ex is System.IO.PathTooLongException)
        {
            System.IO.PathTooLongException exeption = ex as PathTooLongException;
            Error(exeption.ToString());
        }
        else 
        {
            Error(ex.ToString());
        }

        return false;
    }
}


private bool isPathSafe(string path)
{
    //checks to see if the file is hidden or not, if so do not upload
    if ((File.GetAttributes(path) & FileAttributes.Hidden) == FileAttributes.Hidden)
        return false;

    //Checks to see if any of the folders in the path are hidden
    FileInfo fi = new FileInfo(path);
    if (isAnyPathDirHidden(fi.Directory))
        return false;

    //check to see if the file is one of the exception files, if so do not upload.
    return !Regex.IsMatch(path, regexFileExeption, RegexOptions.IgnoreCase | RegexOptions.Singleline);
}

/// <summary>
/// Checks to see if any of the folder's path folders are hidden or not.
/// </summary>
/// <param name="dir">The DirectoryInfo for the currently checked folder</param>
/// <returns>TRUE if the folder is hidden and FALSE if not</returns>
private bool isAnyPathDirHidden(DirectoryInfo dir)
{
    if (dir.Parent == null)
        return false;
    if ((File.GetAttributes(dir.FullName) & FileAttributes.Hidden) == FileAttributes.Hidden)
        return true;
    return isAnyPathDirHidden(dir.Parent);
}

// Upload a local file as a blob.
// Result: 0=success, 1=failed, retry scheduled, 2=failed

private int UploadBlob(BlobTask task)
{
    try
    {
        if (!File.Exists(task.FilePath))
        {
            Warning("   [" + task.BlobName + "]: file not found");
            return 2;
        }

        if (IsFileInUse(task.FilePath))
        {
            Warning("   [" + task.BlobName + "]: file in use");
            task.RemainingRetryCount--;
            if (task.RemainingRetryCount > 0)
            {
                Thread.Sleep(RETRY_SLEEP_INTERVAL);
                lock (BlobQueue)
                {
                    BlobQueue.Add(task);
                }
                return 1;
            }
            return 2;
        }

        if (BlobHelper.PutFileToBlob(task.FilePath, task.ContainerName, task.BlobName))
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }

    // Failed to upload due to a storage service problem.

    catch(StorageException ex)
    {
        Error(ex.ToString());
        Warning("   [" + task.BlobName + "]: storage error");
        task.RemainingRetryCount--;
        if (task.RemainingRetryCount > 0)
        {
            Thread.Sleep(RETRY_SLEEP_INTERVAL);
            lock (BlobQueue)
            {
                BlobQueue.Add(task);
            }
            return 1;
        }
        return 2;
    }

    // Failed to upload due to a file access problem.

    catch (IOException ex)
    {
        Error(ex.ToString());
        Warning("   [" + task.BlobName + "]: could not access file");
        task.RemainingRetryCount--;
        if (task.RemainingRetryCount > 0)
        {
            Thread.Sleep(RETRY_SLEEP_INTERVAL);
            lock (BlobQueue)
            {
                BlobQueue.Add(task);
            }
            return 1;
        }
        return 2;
    }
    catch (Exception ex)
    {
        Error(ex.ToString());
        return 2;
    }
}


// Delete a blob.

private bool DeleteBlob(BlobTask task)
{
    bool ret;
    if (BlobHelper.doesTheBlobExist(task.BlobName, Container))
    {
        ret = DeleteSingleBlob(task.ContainerName, task.BlobName);
    }
    else
    {
        //checks to see if the deletion task is a folder
        //the way it is checked if the virtual folder exists is to check for all subitems (even in subfolders) and then removed all found-
        ret = true;

        CloudBlobContainer container = BlobHelper.BlobClient.GetContainerReference(Container);
        CloudBlobDirectory test = container.GetDirectoryReference(task.BlobName);
        BlobRequestOptions options = new BlobRequestOptions();
        options.UseFlatBlobListing = true;
        IEnumerable<IListBlobItem> blobs = test.ListBlobs(options);
        if (blobs.Count() > 0)
        {
            foreach (IListBlobItem blob in blobs)
            {
                if (blob is CloudBlob)
                {
                    if (!DeleteSingleBlob(task.ContainerName, (blob as CloudBlob).Name))
                    {
                        ret = false;
                    }
                }
            }
        }
    }

    return ret;
}


private bool DeleteSingleBlob(string containerName, string blobName)
{
    try
    {
        return BlobHelper.DeleteBlob(containerName, blobName);
    }
    catch (Exception ex)
    {
        Error(ex.ToString());
        return false;
    }
}
0

There are 0 answers