使用 XmlUriResolver 为远程共享提供凭据

Using XmlUriResolver to provide credentials to remote share

提前感谢您提供的所有帮助。

我在 and other sites on the net (including Microsoft Docs 上看到了几个 post),但是 none 似乎可以帮助解决我的问题。

我正在开发一个项目,该项目连接到来自 WinPE 的远程文件共享上的 xml 文件。我使用了另一个 post 关于使用 XmlUriResolver class 的建议 "moderate" 成功。

我目前面临的问题是 "Access Denied" 错误(多次尝试修改 XmlUriResolver.Credentials class)或没有任何失败原因的完全失败。我假设这将是另一个 "Access Denied" 错误,但我的 try/catch(异常 e)没有捕捉到原因。

下面是我尝试实现的方法的一个片段和相关部分:

relativeSysData = relativeSysData.Replace(@"\", "/");
SysdataXml = $"file://{_globaldata.Server}/{_globaldata.Share}/{relativeSysData}";

XmlUrlResolver XmlResolver = new XmlUrlResolver();
XmlResolver.Credentials = new NetworkCredential(_UserName, 
                                                _Password);

XmlReaderSettings xmlSettings = new XmlReaderSettings();
xmlSettings.XmlResolver = XmlResolver;
LogWriter.WriteLogFile((int)LogWriter.EventID.Xml, (int)LogWriter.EventType.Info,
                      $"Connecting to (remote) System information store at: {SysdataXml}");

xDoc = XDocument.Load(XmlReader.Create(SysdataXml, xmlSettings));
if (xDoc == null)
{
    LogWriter.WriteLogFile((int)LogWriter.EventID.XmlError, (int)LogWriter.EventType.Error,
                          $"Unable to connect to the (remote) data store located at: {SysdataXml}");
    deploy = false;
    capture = false;
    return result;
}

这部分方法专门针对访问远程数据。我有一个包含所有方法的 try/catch 语句。

如果我有到网络共享的开放连接,该方法将完美运行,但会导致该应用程序启动失败 - 由于已经开放连接。

我有一个可能的替代方案来解决这个解决方案,但会花费额外的代码行。

不求助于 WNetAddConnection() 解决此问题的任何帮助将不胜感激

亲切的问候

里奇

N.B。我知道这是一个身份验证问题。

在研究了 XmlUrlResolver class 的工作原理后,我认为可能 referencing/accessing API 未包含在 WinPE API 框架中。

测试后,我使用 WNetAddConnection2() API 连接到服务器并在发生任何事情之前进行身份验证,确保 NETRESOURCE 结构的本地名称保留为空,并且 DisplayType 设置为服务器.

public static int ConnectToServer()
    {
        int result = 0;

        var _netresource = new NetResource()
        {
            scope = _ResourceScope.GlobalNetwork,
            ResourceType = _ResourceType.Any,
            DisplayType = _ResourceDisplayType.Server,
            RemoteName = $@"\{Program._globaldata.Server}"
        };

        string _username = $@"{Program._globaldata.Server}\RemoteDKBuild";
        string _passsword = "Hic3nuasno6epyndtenars4yDifrts";

        var _connectiontype = (int)_ConnectionType.Interactive | (int)_ConnectionType.Temporary;

        LogWriter.WriteLogFile((int)LogWriter.EventID.NetMan, (int)LogWriter.EventType.Info,
                                $@"Attempting to connect to: \{_netresource.RemoteName}");
        result = WNetAddConnection2(_netresource, _passsword, _username, _connectiontype);
        var res = Marshal.GetLastWin32Error();
        if (result !=0)
        {
            LogWriter.WriteLogFile((int)LogWriter.EventID.NetMan, (int)LogWriter.EventType.Error,
                                    $@"Failed to connect to: \{_netresource.RemoteName}, Return Result: {result.ToString()}, Win32 Error Code: {res.ToString()}");
            result = res;
        }
        else
        {
            LogWriter.WriteLogFile((int)LogWriter.EventID.NetMan, (int)LogWriter.EventType.Info,
                                    $@"Connection to: \{_netresource.RemoteName} has been successfull.");
        }

        return result;
    }

[DllImport("mpr.dll", SetLastError = true)]
private static extern int WNetAddConnection2(NetResource netResource, string password, string username, int flags);