MIAIONE 2022-05-18 00:34 采纳率: 100%
浏览 64
已结题

C# 因权限原因找不到文件夹,如何解决?

问题遇到的现象和发生背景

最近在做一个纯HWID的激活项目:https://github.com/MIAIONE/SPPClient
其中KeyManager.cs重写了部分slmgr.vbs,就是通过WMI直接实现了,因为cscript获取输出和执行process类都不太好控制
其中我重写了slmgr中循环遍历文件夹来安装xrm-ms的代码
系统环境:WIN11,VS2022,.NET6 SDK

问题相关代码,请勿粘贴截图

slmgr源实现方法代码:


Private Sub InstallLicenseFiles (strParentDirectory, fso)
    Dim file, files, folder, subFolder

    Set folder = fso.GetFolder(strParentDirectory)
    Set files = folder.Files

    ' Install all license files in folder
    For Each file In files
        If Right(file.Name, 7) = ".xrm-ms" Then
            InstallLicense strParentDirectory & "\" & file.Name
        End If
    Next

    For Each subFolder in folder.SubFolders
        InstallLicenseFiles subFolder, fso
    Next
End Sub

Private Sub ReinstallLicenses()
    Dim shell, fso, strOemFolder
    Dim strSppTokensFolder, folder, subFolder
    Set shell = WScript.CreateObject("WScript.Shell")
    Set fso = CreateObject("Scripting.FileSystemObject")

    strOemFolder = shell.ExpandEnvironmentStrings("%SystemRoot%") & "\system32\oem"
    strSppTokensFolder = shell.ExpandEnvironmentStrings("%SystemRoot%") & "\system32\spp\tokens"

    LineOut GetResource("L_MsgReinstallingLicenses")

    Set folder = fso.GetFolder(strSppTokensFolder)

    For Each subFolder in folder.SubFolders
        InstallLicenseFiles subFolder, fso
    Next

    If (fso.FolderExists(strOemFolder)) Then
        InstallLicenseFiles strOemFolder, fso
    End If

    LineOut GetResource("L_MsgLicensesReinstalled")
End Sub

C#实现(核心遍历文件的代码):


private static List<string> GetAllXrmMSFiles(string rootPath)
        {
            return Directory.EnumerateFiles(rootPath, "*.xrm-ms", SearchOption.AllDirectories).ToList();
        }
运行结果及报错内容

注意这两个目录:
strOemFolder = shell.ExpandEnvironmentStrings("%SystemRoot%") & "\system32\oem"
strSppTokensFolder = shell.ExpandEnvironmentStrings("%SystemRoot%") & "\system32\spp\tokens"
oem基本上不是品牌机不会有,spp\tokens肯定会有
有人试过了,WIN10可以通过管理员CMD 用xcopy复制出来strSppTokensFolder
WIN11资源管理器也可以右键复制出来,只不过要先改文件夹安全设置

C#既然遍历不出来,强制直接new 一个已知存在的路径,用NSUDO用SYSTEM账户+所有权限开启+C#提前添加账户获得完全控制试过了
但是,都直接报 NotFoundDirectory
错误信息:
Unhandled exception. System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Windows\System32\spp\tokens\issuance'.
at System.IO.Enumeration.FileSystemEnumerator1.CreateDirectoryHandle(String path, Boolean ignoreNotFound) at System.IO.Enumeration.FileSystemEnumerator1.Init()
at System.IO.Enumeration.FileSystemEnumerator1..ctor(String directory, Boolean isNormalized, EnumerationOptions options) at System.IO.Enumeration.FileSystemEnumerable1..ctor(String directory, FindTransform transform, EnumerationOptions options, Boolean isNormalized)
at System.IO.Enumeration.FileSystemEnumerableFactory.FileInfos(String directory, String expression, EnumerationOptions options, Boolean isNormalized)
at System.IO.DirectoryInfo.InternalEnumerateInfos(String path, String searchPattern, SearchTarget searchTarget, EnumerationOptions options)
at System.IO.DirectoryInfo.GetFiles(String searchPattern, EnumerationOptions enumerationOptions)
at System.IO.DirectoryInfo.GetFiles()
at SPPClient.Program.Main(String[] args) in D:.NET_6\SPPClient\Program.cs:line 384

而且不是完全遍历不了,里面C:\Windows\System32\spp\tokens\skus\csvlk-pack是可以的,但就只有这一个文件夹和pkeyconfig、legacy可以,其他文件夹当不存在就跳过去了

我的解答思路和尝试过的方法

我用了NSUDO的API和DM模式,这个DM模式我试过,连 System Volume Information 都能遍历,今天却不灵了
首先上面简写自动递归的方法是很好用的,我已经试过手写递归方法了,不行
而且根据这位老哥https://www.cnblogs.com/OpenCoder/p/10482974.html

我想要达到的结果

其实最终目的就是读取所有xrm-ms里面的内容,也就是说,复制出来再读取也可以,我想在C#里完全实现,直接用slmgr肯定是不行的,这样没有事件驱动,看异常应该可以通过直接引用win32api,如果有纯C#解决办法就更好了

  • 写回答

2条回答 默认 最新

  • MIAIONE 2022-05-19 11:28
    关注

    问题解决了:权限我就说都启用SYSTEM用户了,也设置访问权限了,不可能有问题:

    自 Visual Studio 2012 起,C# 应用程序项目默认为“任何首选 CPU 32 位”。如果在 64 位 Windows 操作系统上运行此类可执行文件,则它将作为 32 位进程启动,并受 WOW64 文件系统重定向的影响。

    当 64 位 Windows 上的 32 位进程尝试访问“C:\Windows\System32”时,WOW64 会将其重定向到“C:\Windows\SysWOW64”。有几种方法可以访问真正的“C:\Windows\System32”目录:

    使用“C:\Windows\SysNative”,WOW64将其重定向到“C:\Windows\System32”,即使它没有出现在目录列表中。这是一种简单的方法,不太可能引起问题。
    使用 Wow64DisableWow64FsRedirection 和 Wow64RevertWow64FsRedirection。
    使用 64 位进程。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 5月27日
  • 已采纳回答 5月19日
  • 创建了问题 5月18日

悬赏问题

  • ¥15 Spark加载本地pipelinemodel报错
  • ¥20 电脑鼠标键盘不好使了
  • ¥15 求糕手!用matlab求解目标规划模型🙏
  • ¥15 画出的分类图不对,求解答一下
  • ¥20 springboot和springcloud版本问题
  • ¥15 ps2手柄控制树莓派小车
  • ¥30 C#:vsto powerpoint的外接程序
  • ¥15 两个同维数组相比,不同位置、出现重复比无意义,而不同位置、不出现重复比,则有意义。把有意义的两个数组放入新的集合MK中。
  • ¥15 写一个可直接调用的函数,将32位有符号数转成另一个无符号的数
  • ¥15 CMAKE+VS2019+QT5.15.2组合进行二次编译