不能'T扫描文件夹与空格和特殊的字符如$

FIHOVI.

成员
加入
2019年11月26日
消息
7
编程经验
Beginner
你好,

我想在我的应用程序中扫描驱动器,但我无法扫描$ Recyclebin和文件夹名称中的空格。

我找不到任何解决这些错误的解决方案,我试图找到核心包装,以解决我的解决问题。
我正在使用system.io.

Program.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace FileHandler
{
    class Program
    {
        private static void Main(string[] args)
        {
            GetAllFilesFromFolder(@"E:\", true);
        }

        private static List<string> GetAllFilesFromFolder(string root, bool searchSubfolders)
        {
            Queue<string> folders = new Queue<string>();
            List<string> folderCount = new List<string>();
            List<string> files = new List<string>();
            folders.Enqueue(root);
            while (folders.Count != 0){
                string currentFolder = folders.Dequeue();
                try {
                    string[] filesInCurrent = Directory.GetFiles(currentFolder, "*.*", System.IO.SearchOption.TopDirectoryOnly);
                    files.AddRange(filesInCurrent);
                }
                catch
                {
                    //Console.WriteLine("Error: " + currentFolder);
                    // Do Nothing
                }
                try{
                    if (searchSubfolders){
                        string[] foldersInCurrent = Directory.GetDirectories(currentFolder, "*.*", System.IO.SearchOption.TopDirectoryOnly);
                        foreach (string _current in foldersInCurrent){
                            folderCount.AddRange(foldersInCurrent);
                            folders.Enqueue(_current);
                        }
                    }
                }
                catch{
                    Console.WriteLine("Error: " + currentFolder);
                    // Do Nothing
                }
            }
            countFiles = files.Count();

            List<string> distinct = folderCount.Distinct().ToList(); //Remove Duplicates from scan
            Console.WriteLine("Number of folders AFTER: " + distinct.Count);
            Console.WriteLine("Number of files is: " + files.Count());
       
            Console.ReadLine();
            return files;
        }
    }
}

非常感谢
 
Last edited:

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,893
地点
切萨皮克,va.
编程经验
10+
Directory.GetDirectories() and Directory.GetFiles() returns files and folders with spaces in their name. It also finds the "C:\$Recycle.Bin"
C#:
using System;
using System.IO;

public class Test
{
    static void Main()
    {
        foreach(var f in Directory.GetDirectories(@"C:\"))
        {
            Console.WriteLine(f);
        }
    }
}
capture.png.
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
你似乎不明白的一件事,那是回收站实际上并不是一个文件夹。并且有一个原因它的名字是一个 。微软非常适合使用预期的双关语。您看,回收站实际上是驱动器上的虚拟位置,并且存储在其内的文件也不存在。 Recycle Bin实际上从硬盘驱动器分配了空间,以存储您在虚拟二进制环境中删除的文件。因此,当您删除文件时,它从未真正从PC中删除。相反,它的有点分配了一个容纳文件的原始地址的构建块的模式,以及所有的微粒,这使得它在Windows中预览时看到的功能文件。

但是,任何标记的文件"删除了",简单地分配了一个标志和GUID,它将文件从操作系统设置为我们,但在我们的虚拟目录中几乎可见,直到我们清除垃圾箱。清除垃圾箱的过程只是重新分配的硬盘 比特 它用于构建文件,并且它们被分解并分散在光盘分配区域的各个区域,其中它将被重用并永久覆盖。这就是为什么即使在删除某些东西之后,某些数据仍然可以从硬盘恢复的原因。数据仅分散,直到被叫在以后重复使用。反正...

这是文件看起来像在回收站中迭代它们的内容。这是他们已被移动到虚拟文件夹时。我相信该GUID与硬盘上的下一个地址有关,但我可能会纠正那个。 :
C:\ $ RECYCLE.BIN \ S-1-5-21-3775181533-2454628510-745607798-745607798-745607798-745607798-745607798-745607798-745607798-745607798-745607798-1001 \ $ rywmcqr.xml
C:\ $ RECYCLE.BIN\S-1-5-21-3775181533-2454628510-745607798-1001\$RZWSJHT.txt
如果您在回收站的位置查找目录信息,请在步入调试器时了解更多信息。

screenshot_48.jpg.

请注意它是一个隐藏的 目录,它需要提升的权限,因为它是一个 系统 虚拟的"folder". 最后,无论你打算在回收站中的文件做什么,都可能很难做到。此外,在MSDN上查找已知yolderid,因为它澄清了我上面所说的一些。

编辑
修复了一个错字
 
Last edited:

FIHOVI.

成员
加入
2019年11月26日
消息
7
编程经验
Beginner
Directory.GetDirectories() and Directory.GetFiles() returns files and folders with spaces in their name. It also finds the "C:\$Recycle.Bin"
C#:
using System;
using System.IO;

public class Test
{
    static void Main()
    {
        foreach(var f in Directory.GetDirectories(@"C:\"))
        {
            Console.WriteLine(f);
        }
    }
}
查看附件722.

谢谢你的洞察力,为什么在我的代码中我不能这样做,我的代码遵循
这是来自Catch Block,所有这些文件夹都在E:\下,而不是"E:\ \" - 在我的代码上测试。
wtf.png.

然后与更多文件夹相同..
wtf2.png.

例如...如您猜到,这是在文件夹中"E:\[Alt+0160]\", but not "E:\ [ALT + 0160] \ [ALT + 0160] \"(对不起,与空白的不当行为)

当我在代码中重新创建它时,它仍然是一个问题,
e:\ test \ \ tt(no-breakspace是文件夹本身)
我得到输出:"E:\test\ \ \tt"
你似乎不明白的一件事,那是回收站实际上并不是一个文件夹。并且有一个原因它的名字是一个 。微软非常适合使用预期的双关语。您看,回收站实际上是驱动器上的虚拟位置,并且存储在其内的文件也不存在。 Recycle Bin实际上从硬盘驱动器分配了空间,以存储您在虚拟二进制环境中删除的文件。因此,当您删除文件时,它从未真正从PC中删除。相反,它的有点分配了一个容纳文件的原始地址的构建块的模式,以及所有的微粒,这使得它在Windows中预览时看到的功能文件。

但是,任何标记的文件"删除了",简单地分配了一个标志和GUID,它将文件设置为来自操作系统的文件,但在其虚拟目录中几乎可见,直到我们清除垃圾箱。清除垃圾箱的过程只是重新分配的硬盘 比特 它用于构建文件,并且它们被分解并分散在光盘分配区域的各个区域,其中它将被重用并永久覆盖。这就是为什么即使在删除某些东西之后,某些数据仍然可以从硬盘恢复的原因。数据仅分散,直到被叫在以后重复使用。反正...

这是文件看起来像在回收站中迭代它们的内容。这是他们已被移动到虚拟文件夹时。我相信该GUID与硬盘上的下一个地址有关,但我可能会纠正那个。 :

如果您在回收站的位置查找目录信息,请在步入调试器时了解更多信息。

查看附件723.
请注意它是一个隐藏的 目录,它需要提升的权限,因为它是一个 系统 虚拟的"folder"。最后,无论你打算在回收站中的文件做什么,都可能很难做到。另外,抬头 在MSDN上熟知的梅尔德,因为它澄清了我上面所说的一些。
谢谢你的洞察力。我知道回收站是如何工作的,我与不断的空间混淆,我认为我的代码不会采用任何特殊的角色。
所以我的代码根本不起作用,尽管我找不到任何可疑的任何疑似,为什么我的不断空间在e:\和文件夹本身之间添加了驱动器。
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,893
地点
切萨皮克,va.
编程经验
10+
这是来自Catch块
Say what? If that's in the catch block, then that means an exception is being thrown. What is the exception? Perhaps the message text in the exception will tell you what is failing.
 

FIHOVI.

成员
加入
2019年11月26日
消息
7
编程经验
Beginner
Say what? If that's in the catch block, then that means an exception is being thrown. What is the exception? Perhaps the message text in the exception will tell you what is failing.
e:\ test \ \ \ tt | system.io.directorynotfoundException:找不到路径'e:\ test \ \ tt'的一部分。
在system.io .__错误.WinioError(Int32 ErrorCode,String SolyfullPath)
在system.io.filesystemenumaulterator`1.comneminit()
在system.io.filesystemeNumaulationerator`1..tor(String路径,String OricinalUserPath,Stare SearchPattern,SearchOption SearchOption,SearchResulthandler`1 Resulthandler,Boolean Checkhost)
在system.io.directory.getDirector(String Path,String SearchPattern,SearchOption SearchOption)
在filehandler.program.getallfiles fomfolder(String Root,Boolean SearchSubFolders)中的D:\ Projects \ Filescan \ FileHandler \ Program.CS:第32行
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,893
地点
切萨皮克,va.
编程经验
10+
看起来.NET Framework在处理非破坏空间时有一个错误...它据说是固定的.NET核心,但我猜你正在使用.NET 4.x

查看以下评论​​: 获得儿童和不破坏的空间
 

FIHOVI.

成员
加入
2019年11月26日
消息
7
编程经验
Beginner
看起来.NET Framework在处理非破坏空间时有一个错误...它据说是固定的.NET核心,但我猜你正在使用.NET 4.x

查看以下评论​​: 获得儿童和不破坏的空间
你是对的..我试图使用.NET Framework 4.7.2,它不行..
输出:e:\ test \ \ \ tt
当我把它进入.NET核心
获取以下输出:
e:\ test \ \ tt - >这是一个,我需要它。

非常感谢!
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
顺便说一句,它必须是您的代码中不对的东西。我在4.7.2中尝试了它使用我写自己的代码,没有问题。进一步测试4.8,也没有问题。
 

FIHOVI.

成员
加入
2019年11月26日
消息
7
编程经验
Beginner
我无法识别出问题......我的代码在那里,只有更多或更少..如果你可以在这里发布你的代码来比较它..它会很好。当我将它复制到.NET核心时,没有编辑它。


只有编辑我在项目中完成的.NET框架是ClickOnce安全性的东西(左右)来绕过问题和扫描文件夹和带有管理帐户的文件。但这对我来说没什么意义。
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
使用管理帐户绕过问题和扫描文件夹和文件。
正如我上面所说的那样,所需的行政权利,所以这可能是为什么它没有工作。垃圾箱由系统拥有。

你能首先尝试检查它是否在4.7.2中运行,因为这会发生变化?

对您的唯一区别是我正在使用System32的Shell API,而不是接口。
 

FIHOVI.

成员
加入
2019年11月26日
消息
7
编程经验
Beginner
E:\ \ \ test | system.io.directorynotfoundException:找不到路径'e:\ \ \ test'的一部分。
在system.io .__错误.WinioError(Int32 ErrorCode,String SolyfullPath)
在system.io.filesystemenumaulterator`1.comneminit()
在system.io.filesystemeNumaulationerator`1..tor(String路径,String OricinalUserPath,Stare SearchPattern,SearchOption SearchOption,SearchResulthandler`1 Resulthandler,Boolean Checkhost)
在system.io.directory.getDirector(String Path,String SearchPattern,SearchOption SearchOption)
在FrameworkTest.Prockme.getAllFileSfromFolder(String Root,Boolean SearchSubFolders)中的C:\ Users \ Krogi \ source \ repos \ frameworktest \ frameworktest \ program.cs:line 55
而不是e:\ \ test(\ \ => \[Alt+0160]\)

错误行
Program.cs:
                        string[] foldersInCurrent = Directory.GetDirectories(currentFolder, "*.*", SearchOption.TopDirectoryOnly);

代码块在主要(第一)帖子中可用。

所以它仍然没有工作。普通的新项目,从.NET核心复制的工作代码到.NET Framework 4.7.2并注释为NPGSQL(C#的PostgreSQL驱动程序),因为我不需要或在扫描中使用数据库。
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
那很奇怪。我需要运行代码并在今晚稍后发现更多时间时调试它。我现在喜欢这样做,但我目前正在压力完成我本来应该在上周完成工作但完全忘记的事情。无论如何,我会在发现我的脚并深入研究它。一目了然,它实际上看起来你有问题如何迭代路径,但我稍后会为你检查这个问题。但谢谢你尝试它。 ;)
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,893
地点
切萨皮克,va.
编程经验
10+
这不仅仅是代码。具有目录的环境,其目录是唯一的字符是不打破空间,以复制OP所看到的问题。
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,893
地点
切萨皮克,va.
编程经验
10+
我通过.NET Framework 4.8复制了这个问题:
C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;

class Program
{
    const string RootTestDir = "C:\\TestingNBSPDir";
    static string ChildTestDir = Path.Combine(RootTestDir, "\x00A0\\Leaf");

    static bool EnsureDirectoryExists(string path)
    {
        try
        {
            Console.WriteLine($"Ensuring directory exists: {path}");
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            return true;
        }

        catch (Exception ex)
        {
            Console.Error.WriteLine($"Couldn't access or create {ChildTestDir}");
            Console.Error.WriteLine(ex);
        }
        return false;
    }

    static void RecursivelyListDirectories(string root)
    {
        Console.WriteLine($"Enumerating directories starting at: {root}");
        var queue = new Queue<string>();
        queue.Enqueue(RootTestDir);
        while (queue.Count != 0)
        {
            var current = queue.Dequeue();
            Console.WriteLine($"Working on '{current}'");

            try
            {
                foreach (var dir in Directory.EnumerateDirectories(current, "*", SearchOption.TopDirectoryOnly))
                    queue.Enqueue(dir);
            }

            catch (Exception ex)
            {
                Console.Error.WriteLine(ex);
            }
        }
    }

    static void Main()
    {
        if (EnsureDirectoryExists(ChildTestDir))
            RecursivelyListDirectories(RootTestDir);
    }
}

结果是:
capture.png.png.


和.NET Core 3.0工作正常:
capture2.png.png.
 
Last edited:

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,893
地点
切萨皮克,va.
编程经验
10+
Even though I used EnumerateDirectories() above, GetDirectories() also fails/works the same way.
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,893
地点
切萨皮克,va.
编程经验
10+
另外另一个数据点:让.NET Framework 4.8递归本身正常工作,但在您实际上想要自己行走目录时提供冷舒。
C#:
static void RecursivelyListDirectories(string root)
{
    Console.WriteLine($"Enumerating directories starting at: {root}");
    try
    {
        foreach (var dir in Directory.GetDirectories(root, "*", SearchOption.AllDirectories))
            Console.WriteLine($"Working on '{dir}'");
    }

    catch (Exception ex)
    {
        Console.Error.WriteLine(ex);
    }
}
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
没有真正的选择,如果我已经正确阅读了主题,你提到了ClickOnce。您将无法使用ClickOnce使用提升的权限,因此禁用ClickOnce。右键单击“项目属性”并点击 安全 并禁用 单击一次安全设置。然后添加app.manafest文件并编辑它 asinvoker. is replaced with : <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />. After you decide how to handle this issue with the white space, you may get access denied errors for some of the root files/folders in C:\ or any other drives you search, but we can deal with that next in a separate topic if you need to.

你唯一可以看到的选择是;使用0160预防路径(最佳选项)!您能防止文件夹是否像那样命名?

最有可能不是,我不会建议重命名任何文件或文件夹,除非您的申请负责创建它们。 (假设您的应用程序是某种备份程序。)您还可以录制包含0160的路径,并在应用程序中纠正它们而不触摸原始文件。如果您的应用程序意味着每个文件备份,则可以简单地替换0160并通过调用TRIM()来修复路径,然后某种方式标记需要重命名为0160的路径您是否需要将其恢复为原件名称。

您可以使用字典或外部文件来跟踪文件/文件夹路径,以便使用0160间距以及修剪版本(非0160)版本。假设您的应用程序创建备份或制作所有文件/文件夹路径的记录。如果您曾经需要恢复文件/目录,则只需检查文件以查看需要替换的文件/文件夹是否曾经正式命名为0160,因此您可以复制对操作系统上的正确路径恢复。那有意义吗?

重命名的替代选项正在跳过这些文件和文件夹。您可以使用LINQ调整您的Foreach语句以检查文件或文件夹是否包含0160.以下将检查该路径是否不包含0160的路径并跳过它,如果它确实如下:
C#:
foreach (string _current in foldersInCurrent.Where(s => !s.Contains(@" ")))
Simply use .Where(s => !s.Contains(@" ")) wherever you want to exclude or handle paths containing 0160.
显然,我相信你知道你还可以在路径上调用trim()来删除任何此类的空格等。您还应该使用Dirinfo / FileInfo构建您的Foreach,以避免这样的问题。用 :
foreach(directoryinfo _current等...这意味着重写您的一些代码。
使用简单的字符串不是很好地使用面向对象的代码。您可以使用DirInfo / FileInfo使用更好的功能,并在那里工作。希望这些建议有所帮助。
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
只是为了补充一下,早上凌晨4点,我在漫长的一天后有点过于劳累,所以我希望这是有道理的,如果有一些不明确的东西,我将明天跟着你跟你有任何问题你可能有。 (如果我能醒来。)

晚安。
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,893
地点
切萨皮克,va.
编程经验
10+
作为快速提醒,当.NET Framework 4.6.1更高的尾随字符时,不断的空间(160)只是一个问题。如果它(和其他空格字符)不是尾随字符,则没有问题。另一种绕过问题的方法只是为了转到.NET Core 3.0。
 
Last edited:
最佳 底部