SHFileOperation无法删除文件夹

时间:2015-06-15 10:09:44

标签: c++ wix

我正在为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。上面的代码有什么问题?

1 个答案:

答案 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终止字符串。