谁能帮帮我?
我正在使用 VS2010,C++ 自定义操作项目。尝试使用以下方法从我的 MSI 获取安装位置:
MsiGetTargetPath
但是我不完全理解如何使用它以及他们在 MDSN 上谈论的缓冲区。任何人都可以告诉我或指出正确的方向,因为我在互联网上搜索无济于事。
谢谢
最佳答案
缓冲区处理是 C 和 C++ 编程的一个非常核心的主题。我将从阅读开始。这是我能在短时间内找到的最好的:
- Is there any way to pass a std::string to a function that accepts a char* and changes its contents?
- Pass std::string to a function f(**char)
一旦你理解了这一点,试着从你调用的函数的角度来考虑它。当MsiGetTargetPath被调用,假设其他参数是好的,它计算出路径以查看它和尾随的空字符是否适合 *pcchPathBuf
字符。如果适合,它将路径复制到 szPathBuf
指向的 TCHAR 数组,更新 *pcchPathBuf
以反射(reflect)实际大小,并返回成功。如果不合适,它会更新 *pcchPathBuf
以反射(reflect)它需要的大小(不包括尾随的空字符),并返回 ERROR_MORE_DATA
。
因此您的代码需要传递正确的参数,包括大小合理的缓冲区。我将从 MAX_PATH
开始,然后只需要在一些非常不寻常的情况下增加。请注意,以下代码在所有已知实现中利用了 std::wstring 的实际布局,但在 C++11 之前规范不保证。
// assumes hInstall and strDirectory are defined and correct
std::wstring strPath; // assuming UNICODE here; use std::string if _MBCS instead
DWORD cchPath = MAX_PATH;
strPath.resize(cchPath);
DWORD nResult = ::MsiGetTargetPath(hInstall, strDirectory.c_str(), &strPath[0], &cchPath);
if (nResult == ERROR_MORE_DATA)
{
strPath.resize(++cchPath); // allocate extra spot for trailing null character
nResult = ::MsiGetTargetPath(hInstall, strDirectory.c_str(), &strPath[0], &cchPath);
}
if (nResult == ERROR_SUCCESS)
strPath.resize(cchPath);
else
strPath.clear();
关于c++ - MsiGetTargetPath C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11902603/