英文:
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 <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()
{
// 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 << 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;
// Call WNetGetUniversalName using UNIVERSAL_NAME_INFO_LEVEL option
DWORD result = WNetGetUniversalName(sPath.c_str(), UNIVERSAL_NAME_INFO_LEVEL, (LPVOID)&temp, &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, &bufsize);
if (result == NO_ERROR)
{
sRet = wstring(puni->lpUniversalName);
}
else
{
// Failed to retrieve UNC path
sRet = L"Error retrieving UNC path: " + int_to_wstring(result);
}
delete[] buf;
}
else if (result != NO_ERROR)
{
// Failed to retrieve UNC path
sRet = L"Error retrieving UNC path: " + 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论