任何人都可以帮助我吗?
我正在使用 VS2010,C++ 自定义操作项目。尝试使用以下方法从我的 MSI 获取安装位置:
MsiGetTargetPath
但是我不完全理解如何使用它以及他们在 MDSN 上谈论的缓冲区。任何人都可以告诉我或指出正确的方向,因为我在互联网上搜索无济于事。
谢谢
任何人都可以帮助我吗?
我正在使用 VS2010,C++ 自定义操作项目。尝试使用以下方法从我的 MSI 获取安装位置:
MsiGetTargetPath
但是我不完全理解如何使用它以及他们在 MDSN 上谈论的缓冲区。任何人都可以告诉我或指出正确的方向,因为我在互联网上搜索无济于事。
谢谢
缓冲区处理是 C 和 C++ 编程的核心主题。我会先阅读它。这是我能在短时间内找到的最好的:
一旦你理解了这一点,试着从你正在调用的函数的角度来考虑它。当调用 MsiGetTargetPath时,假设其他参数都很好,它会计算出路径以查看它和一个尾随的空字符是否适合*pcchPathBuf
字符。如果合适,它会将路径复制到 指向的 TCHAR 数组szPathBuf
,更新*pcchPathBuf
以反映实际大小,然后返回成功。如果它不适合,它会更新*pcchPathBuf
以反映它需要的大小(不包括尾随的空字符),并返回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();