使用WNetGetUniversalName函数将本地路径转换为UNC路径时,出现2250错误。

huangapple go评论130阅读模式
英文:

How do I convert local path to UNC in C++ with WNetGetUniversalName function, getting 2250 error

问题

我正在尝试将存储C++可执行文件的本地路径转换为UNC路径,使用Stefan建议的实现方式。但我遇到了2250错误,根据Microsoft的网络管理代码的解释,这意味着'找不到网络连接'。

有没有人知道如何调整我的代码以获取UNC路径?

以下是最小化的代码示例。

#include <iostream>
#include <Windows.h>
#include <sstream>
#include <shlwapi.h>
#include <windows.h>
#include <string>

#pragma comment(lib, "netapi32.lib")
#pragma comment(lib, "Shlwapi.lib")

using namespace std;

std::wstring ConvertToUNC(wstring sPath);

std::wstring GetExecutableDirectory()
{
    // 获取可执行文件的完整路径
    wchar_t buffer[MAX_PATH];
    GetModuleFileName(NULL, buffer, MAX_PATH);

    // 从路径中删除文件名
    PathRemoveFileSpec(buffer);

    return std::wstring(buffer);
}

int main()
{
    std::wstring localPath = GetExecutableDirectory();
    std::wstring uncPath = ConvertToUNC(localPath);

    wcout << L"Local path: " << localPath << endl;
    wcout << L"UNC path: " << uncPath << endl;   

    return 0;
}

std::wstring int_to_wstring(int i) {
    std::wstringstream ss;
    ss << i;
    return ss.str();
}

wstring ConvertToUNC(wstring sPath)
{
    WCHAR temp;
    UNIVERSAL_NAME_INFO* puni = NULL;
    DWORD bufsize = 0;
    wstring sRet = sPath;

    // 使用UNIVERSAL_NAME_INFO_LEVEL选项调用WNetGetUniversalName
    DWORD result = WNetGetUniversalName(sPath.c_str(), UNIVERSAL_NAME_INFO_LEVEL, (LPVOID)&temp, &bufsize);

    if (result == ERROR_MORE_DATA)
    {
        // 现在我们知道需要多大的缓冲区来存储UNC路径
        WCHAR* buf = new WCHAR[bufsize + 1];
        puni = (UNIVERSAL_NAME_INFO*)buf;

        result = WNetGetUniversalName(sPath.c_str(), UNIVERSAL_NAME_INFO_LEVEL, (LPVOID)puni, &bufsize);
        if (result == NO_ERROR)
        {
            sRet = wstring(puni->lpUniversalName);
        }
        else
        {
            // 未能检索UNC路径
            sRet = L"Error retrieving UNC path: " + int_to_wstring(result);
        }

        delete[] buf;
    }
    else if (result != NO_ERROR)
    {
        // 未能检索UNC路径
        sRet = L"Error retrieving UNC path: " + int_to_wstring(result);
    }

    return sRet;
}

我在Visual Studio 2022中作为编码环境,我的操作系统是Windows 11。为了提供背景信息,我是这门语言的新手,仍在学习中。

我尝试了几种排除故障的方法(但没有成功),包括:

  • 检查本地路径是否存在(存在,并且示例代码找到了它)
  • 检查本地路径文件夹中的共享权限
  • 直接从可执行文件(而不是从VS2022调试器)运行C++代码

提前感谢您的帮助。

英文:

I am trying to convert the local path where the C++ executable is stored to a UNC path using the implementation suggested by Stefan. But I get a 2250 error, which according to Microsoft's Network Management Codes means 'The network connection could not be found'

Does anyone know how I can adapt my code to get the UNC path?

Here is minimal reproducing code.

#include &lt;iostream&gt;
#include &lt;Windows.h&gt;
#include &lt;sstream&gt;
#include &lt;shlwapi.h&gt;
#include &lt;windows.h&gt;
#include &lt;string&gt;
#pragma comment(lib, &quot;netapi32.lib&quot;)
#pragma comment(lib, &quot;Shlwapi.lib&quot;)
using namespace std;
std::wstring ConvertToUNC(wstring sPath);
std::wstring GetExecutableDirectory()
{
// Get the full path to the executable file
wchar_t buffer[MAX_PATH];
GetModuleFileName(NULL, buffer, MAX_PATH);
// Remove the file name from the path
PathRemoveFileSpec(buffer);
return std::wstring(buffer);
}
int main()
{
std::wstring localPath = GetExecutableDirectory();
std::wstring uncPath = ConvertToUNC(localPath);
wcout &lt;&lt; L&quot;Local path: &quot; &lt;&lt; localPath &lt;&lt; endl;
wcout &lt;&lt; L&quot;UNC path: &quot; &lt;&lt; uncPath &lt;&lt; endl;   
return 0;
}
std::wstring int_to_wstring(int i) {
std::wstringstream ss;
ss &lt;&lt; i;
return ss.str();
}
wstring ConvertToUNC(wstring sPath)
{
WCHAR temp;
UNIVERSAL_NAME_INFO* puni = NULL;
DWORD bufsize = 0;
wstring sRet = sPath;
// Call WNetGetUniversalName using UNIVERSAL_NAME_INFO_LEVEL option
DWORD result = WNetGetUniversalName(sPath.c_str(), UNIVERSAL_NAME_INFO_LEVEL, (LPVOID)&amp;temp, &amp;bufsize);
if (result == ERROR_MORE_DATA)
{
// Now we have the size required to hold the UNC path
WCHAR* buf = new WCHAR[bufsize + 1];
puni = (UNIVERSAL_NAME_INFO*)buf;
result = WNetGetUniversalName(sPath.c_str(), UNIVERSAL_NAME_INFO_LEVEL, (LPVOID)puni, &amp;bufsize);
if (result == NO_ERROR)
{
sRet = wstring(puni-&gt;lpUniversalName);
}
else
{
// Failed to retrieve UNC path
sRet = L&quot;Error retrieving UNC path: &quot; + int_to_wstring(result);
}
delete[] buf;
}
else if (result != NO_ERROR)
{
// Failed to retrieve UNC path
sRet = L&quot;Error retrieving UNC path: &quot; + int_to_wstring(result);
}
return sRet;
}

I use Visual Studio 2022 as my coding environment, and my OS is Windows 11. For context, I am new to this language and still learning.

I've tried several things to troubleshoot (but had no luck), including:

  • checking the local path exists (it does, and is found by the sample code)
  • checking the sharing permissions within the local path folder
  • running the C++ code directly from the executable (instead of the VS2022 debugger)

Thank you in advance.

答案1

得分: 2

我遇到了2250错误,根据Microsoft的网络管理代码的解释,这表示'找不到网络连接'。

在这种情况下,错误2250指的是标准系统错误ERROR_NOT_CONNECTED,而不是网络错误NERR_UseNotFound,尽管它们具有相同的数字值。

如果你阅读WNetGetUniversalName()本身的文档,它说:

WNetGetUniversalName函数接受一个网络资源的基于驱动器的路径,并返回一个包含更通用名称形式的信息结构。
...
如果函数失败,返回值是系统错误代码,如以下值之一。

返回代码 描述
ERROR_NOT_CONNECTED lpLocalPath参数指定的设备未重定向。

基本上,这意味着你传递给WNetGetUniversalName()的路径只是本地路径,它没有使用映射到网络共享的驱动器号,因此无法检索UNC路径。

英文:

> I get a 2250 error, which according to Microsoft's Network Management Codes means 'The network connection could not be found'

In this situation, error 2250 is referring to the standard system error ERROR_NOT_CONNECTED, not the network error NERR_UseNotFound, which happens to have the same numeric value.

If you read the documentation for WNetGetUniversalName() itself, it says:

> The WNetGetUniversalName function takes a drive-based path for a network resource and returns an information structure that contains a more universal form of the name.
>
> ...
>
> If the function fails, the return value is a system error code, such as one of the following values.
>
> | Return code | Description |
> | ----------- | ----------- |
> | ERROR_NOT_CONNECTED | The device specified by the lpLocalPath parameter is not redirected. |

Basically, that means the path you are passing in to WNetGetUniversalName() is just a local path, it is not using a drive letter that is mapped to a network share, hence there is no UNC path to retrieve for it.

huangapple
  • 本文由 发表于 2023年2月23日 22:45:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75546373.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定