.NET5.0程序发布为自包含应用后无法找到System32下的dsregcmd.exe文件
问题原因
这是64位Windows系统的32位程序文件系统重定向机制导致的:
- 64位Windows中,
C:\Windows\System32目录默认存储64位系统文件,32位程序访问该路径时,系统会自动将请求重定向到存储32位系统文件的C:\Windows\SysWOW64目录,你要查找的dsregcmd.exe是仅存在于64位System32目录的64位程序,32位进程重定向后自然找不到。 - 你在Visual Studio或直接用dotnet命令运行时,默认调用的是64位.NET运行时,程序以64位进程运行,不会触发重定向,可以正常访问真实的System32目录;而发布时指定了
-r win-x86参数,生成的是32位自包含程序,运行时是32位进程,就触发了重定向逻辑。
解决方案
可以根据你的需求选择任意一种方案:
- 发布64位程序:将发布命令中的运行时标识从
win-x86改为win-x64,修改后的发布命令如下:
生成的64位程序不会触发文件系统重定向,可正常访问System32目录。dotnet publish ".\MyProject.csproj" -c Release -r win-x64 --self-contained -o ".\output" - 使用Sysnative别名访问真实System32目录:如果必须使用32位程序,可以将路径中的
System32替换为Sysnative,这是系统预留的专门给32位程序访问64位System32目录的别名,修改后的代码如下:public static void Main(string[] args) { Console.WriteLine(File.Exists(@"C:\WINDOWS\Sysnative\dsregcmd.exe")); Directory.GetFiles(@"C:\WINDOWS\Sysnative\").ToList().ForEach(f => Console.WriteLine(f)); } - 临时禁用文件系统重定向:通过P/Invoke调用Windows API临时关闭32位进程的文件系统重定向,操作完成后再恢复,代码示例如下:
[DllImport("kernel32.dll", SetLastError = true)] public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr); public static void Main(string[] args) { IntPtr ptr = IntPtr.Zero; try { Wow64DisableWow64FsRedirection(ref ptr); Console.WriteLine(File.Exists(@"C:\WINDOWS\system32\dsregcmd.exe")); Directory.GetFiles(@"C:\WINDOWS\system32\").ToList().ForEach(f => Console.WriteLine(f)); } finally { Wow64RevertWow64FsRedirection(ptr); } }
内容的提问来源于stack exchange,提问作者Mohammad Fneish
相关产品推荐
相关产品推荐

