System.DirectoryServices.Interop.UnsafeNativeMethods.IAds.GetInfo()引发了FileNotFoundException异常。

9

我有一行简单的代码:

var entry = new DirectoryEntry("WinNT://DOMAIN/MachineName, Computer");
Console.WriteLine(entry.Guid);

实际上,路径是由命令行提供的。这个简单的控制台应用程序编译用于测试,在我的测试中,我发现:
- 连接到自己的 Windows 7 PC 可以工作。 - 连接到网络上的任何其他 Windows XP 机器都可以工作。 - 连接到网络上的任何其他 Windows 7 机器都会失败,并显示以下错误信息:
``` Unhandled Exception: System.IO.FileNotFoundException: The network path was not found. at System.DirectoryServices.Interop.UnsafeNativeMethods.IAds.GetInfo() at System.DirectoryServices.DirectoryEntry.RefreshCache() at System.DirectoryServices.DirectoryEntry.FillCache(String propertyName) at System.DirectoryServices.DirectoryEntry.get_NativeGuid() at System.DirectoryServices.DirectoryEntry.get_Guid() at GetDirectoryEntryProperties.Program.Main(String[] args) in D:\GetDirectoryEntryProperties\Program.cs:line 15 ```
有什么想法吗?
我在所有计算机上都是管理员,但我确实遇到了另一个问题,由设备锁定服务引起的 UnauthorizedAccessException,导致无法读取机器的 GUID。
事件日志没有显示任何有用的信息。
Luke

我认为你需要将WinNT://更改为适用于Windows 7机器。这只是一个猜测。 - Malachi
你能展示更多的代码吗?你的错误最后一行引用了 D:\GetDirectoryEnttryProperties\Program.cs:line 15,而 .csC# 文件的扩展名。 - Malachi
嗨Malione,这只是代码(顶部)所在的文件。它只是一个测试控制台应用程序的Program类。 - Luke Puplett
我假设您可以物理访问您要通信的机器。您能否查看您尝试连接的路径名的文件目录是否存在?如果有意义的话。 - Malachi
我相信在Vista及以后的版本中,您实际上需要更改防火墙/安全设置才能允许远程访问本地WinNT提供程序。 - Joe Caffeine
显示剩余3条评论
2个回答

13

我在不同的情况下遇到了相同的错误信息。也许我找到的解决方案也可以帮助你。

升级到Windows 10后,我的计算机在启动时弹出一个错误提示,看起来就像你发布的那一个。这是一个FileNotFoundException,位于System.DirectoryServices.Interop.UnsafeNativeMethods.IAds.GetInfo()。

解决方案是将两个字符串从一个注册表位置复制到另一个位置。

Copy these strings: RegisteredOwner and RegisteredOrganization

From: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion

To: HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion

1
感谢Bryan回来发帖。我已经不再从事这方面的工作了,但也许有一天我会回到那个领域。 - Luke Puplett
1
谢谢Bryan,这个方法对我有用(Win 10已升级多次)。我原本是用新的PrincipalContext(ContextType.Machine, Environment.MachineName)来打开连接的,但在调用FindAll()时出现了FileNotFoundException异常。 - tbt
基于tburi的评论,将以下程序相关内容从英语翻译为中文。请仅返回翻译后的文本。 - Luke Puplett

0

我想感谢Bryan Roach,因为他的帮助我解决了我的问题。我也意识到我可以将我的C#项目构建设置为平台目标x64,从而避免错误,因为它会搜索64位注册表区域。然而,我认为对于我的应用程序来说,选择Any CPU更为合适,让程序本身能够解决这个问题。

string ServerName = "REMOTE_COMPUTER";
PrincipalSearcher pSearch = new PrincipalSearcher();
pSearch.QueryFilter = new UserPrincipal(new PrincipalContext(ContextType.Machine, ServerName, null, ContextOptions.Negotiate));

try
{
    foreach (UserPrincipal userUP in pSearch.FindAll())
    {
         //Missing Registry Keys will error on pSearch.FindAll();
         //Either Build > Platform Target == x64 or deal with it.
    }
}
catch(FileNotFoundException ex)
{
    if(ex.Source.Equals("Active Directory") && 
       ex.TargetSite.MemberType.ToString().Equals("Method") && 
       ex.TargetSite.Name.Equals("GetInfo"))
    {
        //It's possible the registry keys haven't been moved to x86 location on a 64 bit machine:
        //From: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion (64 bit)
        //To: HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion (32 bit compatability area)
        //String Properties need to be present:  RegisteredOwner, RegisteredOrganization
        try
        {
            Hack_Fixx64RegistryForGettingLocalAccounts(ServerName);
            //Recall function or whatever to try again with fixed registry.
        }
        catch
        { }
    }
}

然后是将注册表键复制到正确位置的函数:

private void Hack_Fixx64RegistryForGettingLocalAccounts(string ServerName)
{
    RegistryKey remoteKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, ServerName, RegistryView.Registry64);
    if(remoteKey != null)
    {
        //Get keys stored on 64 bit location
        RegistryKey x64regkey = remoteKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
        string regOwner = Convert.ToString(x64regkey.GetValue("RegisteredOwner", ""));
        string regOrganization = Convert.ToString(x64regkey.GetValue("RegisteredOrganization", ""));
        //Add missing keys on 64 bit OS in correct location for 32 bit registry area. The Wow6432Node is for 32-bit apps that run on 64-bit window versions.
        remoteKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, ServerName, RegistryView.Registry32);
        if(remoteKey != null)
        {
            RegistryKey x86regkey = remoteKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", true);
            x86regkey.SetValue("RegisteredOwner", regOwner);
            x86regkey.SetValue("RegisteredOrganization", regOrganization);
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接