簡體   English   中英

HRESULT轉換為字符串(獲取文檔路徑)C ++

[英]HRESULT to string (getting documents path) C++

我正在使用以下功能來嘗試獲取documents文件夾的路徑,然后將該路徑轉換為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 已知的文件夾路徑是可自定義的(請參閱“ 文件夾重定向概述” )。 您不能簡單地嘗試自己構建它們。 您必須要求Shell提供此信息。

我最終放棄了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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM