我用这个绳子到达了最后。我有一些C#代码试图将包含映射到网络驱动器的驱动器号(例如“S:\”)的路径解析为UNC路径(例如“\\ server \ share \”)。我是通过P / Invoke使用WNetGetUniversalName来做这件事,但在我的一些同事的机器上(不是我的,烦人)我看到该函数一直失败,错误代码为ERROR_NOT_SUPPORTED。
以下是代码:
[DllImport("mpr.dll", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.U4)]
static extern int WNetGetUniversalName(
string lpLocalPath,
[MarshalAs(UnmanagedType.U4)] int dwInfoLevel,
IntPtr lpBuffer,
[MarshalAs(UnmanagedType.U4)] ref int lpBufferSize);
/// <summary>
/// Gets the UNC path for the path passed in.
/// </summary>
/// <param name="path">The path for which we want the UNC path.</param>
/// <returns>The UNC path. Returns empty string if an error has occurred. </returns>
public static string GetUniversalPath(string path)
{
const int UNIVERSAL_NAME_INFO_LEVEL = 0x00000001;
const int ERROR_MORE_DATA = 234;
const int NOERROR = 0;
string retVal = null;
// Pointer to the memory buffer to hold the result.
IntPtr buffer = IntPtr.Zero;
try
{
// First, call WNetGetUniversalName to get the size.
// Passing (IntPtr)IntPtr.Size as the third parameter because WNetGetUniversalName doesn't
// like NULL, and IntPtr.Size will always be a properly-aligned (if not actually valid)
// IntPtr value.
int size = 0;
int apiRetVal = WNetGetUniversalName(path, UNIVERSAL_NAME_INFO_LEVEL, (IntPtr)IntPtr.Size, ref size);
if (apiRetVal == ERROR_MORE_DATA)
{
// Allocate the memory.
buffer = Marshal.AllocCoTaskMem(size);
// Now make the call.
apiRetVal = WNetGetUniversalName(path, UNIVERSAL_NAME_INFO_LEVEL, buffer, ref size);
if (apiRetVal == NOERROR)
{
// Now get the string. It's all in the same buffer, but
// the pointer is first, so offset the pointer by IntPtr.Size
// and pass to PtrToStringAnsi.
retVal = Marshal.PtrToStringAuto(new IntPtr(buffer.ToInt64() + IntPtr.Size), size);
retVal = retVal.Substring(0, retVal.IndexOf('\0'));
}
}
}
catch
{
// I know swallowing exceptions is nasty...
retVal = "";
}
finally
{
Marshal.FreeCoTaskMem(buffer);
}
return retVal;
}
第一次调用WNetGetUniversalName时,我看到了ERROR_NOT_SUPPORTED返回值。就像我说的那样,它每次都在我的机器上运行,但它似乎总是在其他机器上失败。
更新:我应该补充一点,在所有情况下,使用的操作系统都是带有Service Pack 1的Windows 7 Enterprise x64。
更新2:我应该更加清楚我混淆的原因。该文档指出ERROR_NOT_SUPPORTED意味着没有网络提供商支持UNC名称。但是,UNC名称在我看过这个问题的每台机器上运行良好。我想知道是否有人之前已经看到这个和/或可能能够为ERROR_NOT_SUPPORTED返回提供其他可能的解释。
答案 0 :(得分:3)
documentation表示此返回值表示:
dwInfoLevel参数设置为UNIVERSAL_NAME_INFO_LEVEL,但网络提供程序不支持UNC名称。 (没有网络提供商支持此功能。)
除此之外还有更多内容。
答案 1 :(得分:2)
知道了!经过一番挖掘,我找到了问题的根源。呼叫不起作用的机器安装了名为“Pismo File Mount”的网络提供商,显然是Pismo File Mount Audit Package的一部分。
我找到了已安装网络提供商的列表,如下所示:
这就是我所看到的:
我能够通过以下方式解决问题:
我仍然不理解我想要的问题,但至少我们有一些东西可以告诉客户他们是否遇到过这个问题。