1

Can anyone help me please?

I'm using VS2010, C++ Custom Action Project. Trying to get the install location from my MSI using:

MsiGetTargetPath

However I don't fully understand how to use it and the buffer they talk about on MDSN. Could anyone tell me or point me in the correct direction as I've searched the internet to no avail.

Thanks

Natalie Carr
  • 3,707
  • 3
  • 34
  • 68

1 Answers1

1

Buffer handling is a pretty core topic to C and C++ programming. I would start by reading up on that. Here's the best I could find on short notice:

Once you understand that, try to think about it from the point of view of the function you're calling. When MsiGetTargetPath is called, assuming the other parameters are good, it figures out the path to see if it and a trailing null character fit in *pcchPathBuf characters. If it fits, it copies the path to the TCHAR array pointed to by szPathBuf, updates *pcchPathBuf to reflect the actual size, and returns success. If it does not fit, it updates *pcchPathBuf to reflect the size it needs (excluding the trailing null character), and returns ERROR_MORE_DATA.

So your code needs to pass correct parameters, including a buffer of reasonable size. I'd start with MAX_PATH and then only have to increase in some very unusual cases. Note that the following code takes advantage of the actual layout of std::wstring in all known implementations, but isn't guaranteed by the specification until 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();
Community
  • 1
  • 1
Michael Urman
  • 15,737
  • 2
  • 28
  • 44