HRESULT到字符串(获取文档路径)C++

HRESULT to string (getting documents path) C++

本文关键字:路径 C++ 文档 获取 字符串 HRESULT      更新时间:2023-10-16

我使用以下函数尝试获取文档文件夹的路径,然后将该路径转换为std::string:

std::string getpath() {
    TCHAR documents[MAX_PATH];
    HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documents);
    std::stringstream pff;
    pff << result;
    return pff.str();
}

当执行此操作时,当尝试将"\filename"附加到字符串时,会出现"无效文件名错误"。

请帮忙!

编辑:以下是我如何附加到路径:

std::string folder = getpath() + "\Folder";

我以为双转义符仍然适用。

您打印的不是documents,而是result

试试这样的东西:

std::string getpath() {
    TCHAR documents[MAX_PATH];
    HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documents);
    if (result == S_OK) // SUCCEEDED(result) can be problematic
                        // since S_FALSE is a possible return value
    {
        std::stringstream pff;
        pff << documents;
        return pff.str();
    }
    // handle error somehow
    return "";
}

这是一个Unicode友好版本:

std::wstring getpath() {
    TCHAR documents[MAX_PATH];
    HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documents);
    if (result == S_OK) // SUCCEEDED(result) can be problematic
        // since S_FALSE is a possible return value
    {
        std::wstringstream pff;
        pff << documents;
        return pff.str();
    }
    // handle error somehow
    return L"";
}

您的代码失败了,因为您实际上是在用SHGetFolderPath的返回值(即错误代码)构造字符串。您应该使用返回的路径。

由于SHGetFolderPath已弃用,因此应改用SHGetKnownFolderPath。除其他外,您不会意外地构造MBCS编码的路径名。并且不存在任意的MAX_PATH(260)字符限制。

以下代码检索当前用户的文档路径1:

#include <string>
#include <ShlObj.h>
#include <comdef.h>
std::wstring GetDocumentPath() {
    wchar_t* pOut = nullptr;
    // Retrieve document path (CheckError throws a _com_error exception on failure)
    _com_util::CheckError( ::SHGetKnownFolderPath( FOLDERID_Documents, KF_FLAG_DEFAULT,
                                                   nullptr, &pOut ) );
    // Attach returned buffer to a smart pointer with custom deleter. This
    // is necessary, because the std::wstring c'tor throws on failure.
    // Without this smart pointer, any exception would leak memory.
    auto deleter = []( void* p ) { ::CoTaskMemFree( p ); };
    std::unique_ptr<wchar_t, decltype( deleter )> buffer{ pOut, deleter };
    return std::wstring{ buffer.get() };
    // Invisible: Run deleter for buffer, cleaning up allocated resources.
}

注意:_com_util::CheckError没有正式文档,因此它可能在未来版本的编译器中不可用。具有类似功能的自定义实现可能如下所示:

inline void CheckError( HRESULT hr ) {
    if ( FAILED( hr ) ) {
        _com_raise_error( hr );
    }
}

_com_raise_error被记录为抛出_com_error异常。FAILED宏也有文档记录。


1已知的文件夹路径是可自定义的(请参阅文件夹重定向概述)。你不能简单地试图自己构建它们。你必须向壳牌公司索取这些信息

我最终放弃了SHGetFolderPath,转而使用更简单的_dupenv_s:

std::string getpath() {
    char* buf = 0;
    size_t sz = 0;
    if (_dupenv_s(&buf, &sz, "USERPROFILE") == 0) {
        std::string path(buf);
        path += "\Documents\Folder";
        return path;
    }
    return NULL;
}