WNetAddConnection2 返回错误 1200 - 本地名称有效

Posted

技术标签:

【中文标题】WNetAddConnection2 返回错误 1200 - 本地名称有效【英文标题】:WNetAddConnection2 returns Error 1200 - Local name is valid 【发布时间】:2017-07-27 05:58:07 【问题描述】:

我正在尝试将共享(比如说 \server\folder)连接到我的本地设备 X:

[DllImport("Mpr.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        private static extern int WNetAddConnection2(
            [In] NetResource lpNetResource,
            string lpPassword,
            string lpUsername,
            int flags
        );

public static bool Connect(string remoteName, string localName, bool persistent) 
            if (!IsLocalPathValid(localName)) return false;
            var r = new NetResource
            
                dwScope = ResourceScope.RESOURCE_GLOBALNET,
                dwType = ResourceType.RESOURCETYPE_ANY,
                dwDisplayType = ResourceDisplayType.RESOURCEDISPLAYTYPE_SHARE,
                dwUsage = ResourceUsage.RESOURCEUSAGE_CONNECTABLE,
                lpRemoteName = remoteName,
                lpLocalName = localName
            ;
            return WNetAddConnection2(r, null, null, persistent ? 1 : 0) == 0;
        

[StructLayout(LayoutKind.Sequential)]
    public class NetResource 
        public ResourceScope dwScope;
        public ResourceType dwType;
        public ResourceDisplayType dwDisplayType;
        public ResourceUsage dwUsage;
        public string lpLocalName;
        public string lpRemoteName;
        public string lpComment;
        public string lpProvider;
    

调用时

Connect(@"\\server\folder", "X:", true);

该函数只返回 false - 错误为 1200 (BAD_DEVICE)。 NetResource 如下所示:

lpRemoteName = "\\\\server\\folder"; 
lpProvider = null;
lpLocalName = "X:";
lpComment = null;
dwUsage = Connectable; 
dwType = Any; 
dwScope = GlobalNet; 
dwDisplayType = Share;

我已经检查了几个 sn-ps (PInvoke),我看不出有什么不同。或许你能解开这个谜团……

EDIT1

【问题讨论】:

如果您不提供本地名称,地图驱动器是否工作?即,将 localName 设为空字符串。这可能会提供一些线索,是否还有其他问题。错误代码 1200 表示您的“X:\”有问题 - 是否有多余的空格(请参阅 - ***.com/questions/31137879/…) 不幸的是,错误 1200 仍然存在,即使没有指定本地驱动器(空字符串)。有关更多 NetResource 详细信息,请参阅我的 Edit1。 (我不得不清除服务器名称,抱歉。 【参考方案1】:
[StructLayout(LayoutKind.Sequential)]

那是问题开始的地方,属性没有指定CharSet属性。默认值为 CharSet.Ansi,这是一个令人眼花缭乱的选择,需要在时间机器中旅行才能理解,带您回到 1998 年。因此,代码将一个带有字符串的结构传递给一个函数,该字符串被转换为 8 位字符显式使用函数的 Unicode 风格。不可避免地,实现会看到垃圾。

您可以使用 [MarshalAs] 强制对每个单独的字符串成员进行编组。但是使字符类型匹配更简单和合乎逻辑。修复:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]

【讨论】:

【参考方案2】:

我终于做到了。

我通过添加解决了这个问题

[MarshalAs(UnmanagedType.LPWStr)] 

我的 NetResource 类中每个字符串字段的属性。不幸的是,我不知道为什么这可以解决问题...

【讨论】:

以上是关于WNetAddConnection2 返回错误 1200 - 本地名称有效的主要内容,如果未能解决你的问题,请参考以下文章

如何解决 WNetAddConnection2 中的此错误“ERROR_BAD_USERNAME”?

WNetAddConnection2 在 Windows 2008 R2 中不起作用

使用空本地名称调用 WNetAddConnection2

WINDOWS API函数说明

Windows API函数大全(完整)

win32 API