WNetAddConnection2 returns 错误 1200 - 本地名称有效
WNetAddConnection2 returns Error 1200 - Local name is valid
我正在尝试将共享(比方说 \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);
函数只是 returns false - 错误显示 1200 (BAD_DEVICE)。
NetResource 看起来像这样:
lpRemoteName = "\\server\folder";
lpProvider = null;
lpLocalName = "X:";
lpComment = null;
dwUsage = Connectable;
dwType = Any;
dwScope = GlobalNet;
dwDisplayType = Share;
我已经检查了几个片段 (PInvoke),我看不出有什么不同。也许你能解开这个谜...
EDIT1
我终于做到了
我通过添加
解决了这个问题
[MarshalAs(UnmanagedType.LPWStr)]
我的 NetResource class 中每个字符串字段的属性。不幸的是,我不知道为什么这可以解决问题...
[StructLayout(LayoutKind.Sequential)]
那就是问题开始的地方,属性没有指定CharSet
属性。默认值为 CharSet.Ansi,这是一个令人困惑的选择,需要乘坐时光机才能理解,带您回到 1998 年。因此,代码将带有字符串的结构传递给一个函数,该字符串被转换为 8 位字符明确使用函数的 Unicode 风格。不可避免地,实现会看到垃圾。
您可以使用 [MarshalAs] 强制封送每个单独的字符串成员。但是使字符类型匹配更简单和合乎逻辑。修正:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
我正在尝试将共享(比方说 \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);
函数只是 returns false - 错误显示 1200 (BAD_DEVICE)。 NetResource 看起来像这样:
lpRemoteName = "\\server\folder";
lpProvider = null;
lpLocalName = "X:";
lpComment = null;
dwUsage = Connectable;
dwType = Any;
dwScope = GlobalNet;
dwDisplayType = Share;
我已经检查了几个片段 (PInvoke),我看不出有什么不同。也许你能解开这个谜...
EDIT1
我终于做到了
我通过添加
解决了这个问题[MarshalAs(UnmanagedType.LPWStr)]
我的 NetResource class 中每个字符串字段的属性。不幸的是,我不知道为什么这可以解决问题...
[StructLayout(LayoutKind.Sequential)]
那就是问题开始的地方,属性没有指定CharSet
属性。默认值为 CharSet.Ansi,这是一个令人困惑的选择,需要乘坐时光机才能理解,带您回到 1998 年。因此,代码将带有字符串的结构传递给一个函数,该字符串被转换为 8 位字符明确使用函数的 Unicode 风格。不可避免地,实现会看到垃圾。
您可以使用 [MarshalAs] 强制封送每个单独的字符串成员。但是使字符类型匹配更简单和合乎逻辑。修正:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]