1

任何人都可以帮助我吗?

我正在使用 VS2010,C++ 自定义操作项目。尝试使用以下方法从我的 MSI 获取安装位置:

MsiGetTargetPath

但是我不完全理解如何使用它以及他们在 MDSN 上谈论的缓冲区。任何人都可以告诉我或指出正确的方向,因为我在互联网上搜索无济于事。

谢谢

4

1 回答 1

1

缓冲区处理是 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();
于 2012-08-11T13:37:31.397 回答