我正在为WiX编写C ++ Custom操作,在安装过程中将调用该操作以删除安装程序安装的任何剩余部分。请考虑以下代码:
$file = 'dir/test.php';
unlink($file );
在上面的代码中,我们在UINT __stdcall DeleteResidue(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
LPWSTR lpFolderPath = NULL;
std::wstring temp;
SHFILEOPSTRUCT shFile;
hr = WcaInitialize(hInstall, "DeleteResidue");
ExitOnFailure(hr, "Failed to initialize");
hr = WcaGetProperty(L"LPCOMMAPPDATAFOLDER",&lpFolderPath);
ExitOnFailure(hr, "Failure in Finding Common App Data Folder");
temp = std::wstring(lpFolderPath);
temp+=L"\0\0";
//Stop the LPA and LPA Monitor Service. Then delete the residue.
WcaLog(LOGMSG_STANDARD, "Doing Delete Residue");
ZeroMemory(&shFile, sizeof(shFile));
shFile.hwnd = NULL;
shFile.wFunc = FO_DELETE;
shFile.pFrom = temp.c_str();
shFile.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI;
BOOL res = DirectoryExists(lpFolderPath);
if(res)
{
WcaLog(LOGMSG_STANDARD, "The directory exist");
int result = SHFileOperation(&shFile);
if(!result)
WcaLog(LOGMSG_STANDARD, "The directory should have deleted by now");
else
WcaLog(LOGMSG_STANDARD, "The directory could not be deleted.Error code %d", result);
}
else
{
WcaLog(LOGMSG_STANDARD, "It Seems the Installed Folder is No more there");
}
LExit:
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
return WcaFinalize(er);
}
中获得C:\ProgramData
。该文档声明LPCOMMAPPDATAFOLDER
应为pFrom
。但是,代码的返回值为double null terminated
,即0x2
。上面的代码有什么问题?
答案 0 :(得分:2)
你不是双重终止pFrom
。
您有一个标准字符串(当您在其上调用.c_str()
时包含空终结符)。
temp = std::wstring(lpFolderPath);
然后将空字符串连接到它上面:
temp+=L"\0\0";
这使原始字符串保持不变。这是因为std::string::operator+(const wchar_t*)
采用空终止字符串。你有2个空值这一事实并不重要,只能读取第一个空值。它甚至没有添加null,因为你实际上它是一个空字符串,并且将空字符串连接到其他东西的结果是no-op。
有几种方法可以解决这个问题,但最简单的方法就是改变
temp+=L"\0\0";
到
temp.push_back(L'\0');
显式地向字符串添加了另一个nul,所以当你最后调用temp.c_str()
时,你将获得你需要的双nul终止字符串。