我使用以下函数尝试获取文档文件夹的路径,然后将该路径转换为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;
}