我正在尝试将 CString
转换为 LPCWSTR
并且效果很好。但是在代码处理过程中出了点问题。
我想将目录复制到另一个路径,所以我使用 SHFILEOPSTRUCT
:
HWND console = GetConsoleWindow();
SHFILEOPSTRUCT s = { 0 };
s.hwnd = console;
s.wFunc = FO_COPY;
s.fFlags = FOF_SILENT;
CString _folderName("a6_töüst-Oa5Z.OZS-CI5O5235"),
firstPath("C:\\ORTIM-Daten\\a5Pc 2.0.3\\Temp\\"),
lastPart("\\Documents\\*\0"),
firstPathDest("C:\\ORTIM-Daten\\a5Pc 2.0.3\\"),
lastPartDest("Documents\\"),
_folderNameDest("a6_töüst-Oa5Z.OZS-CI5O5235\0");
CString cstrTemp = firstPath + _folderName + lastPart,
cstrTempDest = firstPathDest + lastPartDest + _folderNameDest;
s.pTo = cstrTempDest /*_TEXT("C:\\ORTIM-Daten\\a5Pc 2.0.3\\Documents\\a6_töüst-Oa5Z.OZS-CI5O5235\0")*/;
s.pFrom = cstrTemp /*_TEXT("C:\\ORTIM-Daten\\a5Pc 2.0.3\\Temp\\a6_töüst-Oa5Z.OZS-CI5O5235\\Documents\\*\0")*/;
SHFileOperation(&s);
当我直接使用 CString
时,复制操作不起作用,但是当我使用 _TEXT()
宏(如评论中)来分配LPCWSTR
结构中的成员一切正常。
编辑 1
代码在源路径和目标路径的两种变体中编译。
在此变体中,代码编译并执行复制操作:
s.pTo = _TEXT("C:\\ORTIM-Daten\\a5Pc 2.0.3\\Documents\\a6_töüst-Oa5Z.OZS-CI5O5235\0");
s.pFrom = _TEXT("C:\\ORTIM-Daten\\a5Pc 2.0.3\\Temp\\a6_töüst-Oa5Z.OZS-CI5O5235\\Documents\\*\0");
在我实际需要的另一个变体中,代码也可以编译,但复制操作不会发生:
s.pTo = cstrTempDest;
s.pFrom = cstrTemp;
最佳答案
SHFILEOPSTRUCT
需要以两个 NUL 字符结尾的字符串,但根据定义,NUL 终止字符串以一个 结尾,并且任何其他 NUL 字符都将被忽略不采用显式长度参数的 CString
方法。
您可以通过手动添加一个来强制使用双 NUL:
CString cstrTempDest = firstPathDest + lastPartDest + _folderNameDest;
// *** Add NUL manually ***
cstrTempDest.AppendChar( 0 );
s.pTo = cstrTempDest;
// For debuging - verify resulting string with example.
TCHAR* test = _TEXT("C:\\ORTIM-Daten\\a5Pc 2.0.3\\Documents\\a6_töüst-Oa5Z.OZS-CI5O5235\0");
// +2 because we want to check two NULs at end.
ASSERT( memcmp( s.pTo, test, (_tcslen(test)+2)*sizeof(TCHAR) ) == 0 );
替代解决方案可以使用带有显式长度参数的方法:
CString cstrTempDest = firstPathDest + lastPartDest
+ CString(_folderNameDest, _tcslen(_folderNameDest)+1);
如果您的项目配置为使用 unicode 字符集,请使用宽字符串调用 CString
构造函数:
CString _folderName(_T("a6_töüst-Oa5Z.OZS-CI5O5235")),
firstPath(_T("C:\\ORTIM-Daten\\a5Pc 2.0.3\\Temp\\"))
...
unicode 模式下的 CString
会自动将窄字符串转换为宽字符串,但当运行时和开发代码页之间存在差异时,它可能会失败。如果您打算使用 Unicode 并且永不回头,请扔掉 _TEXT
、TEXT
和 _T
宏,只使用宽文字:
CString _folderName( L"a6_töüst-Oa5Z.OZS-CI5O5235" ),
firstPath( L"C:\\ORTIM-Daten\\a5Pc 2.0.3\\Temp\\" )
...
您还应该检查 SHFileOperation
返回值。
关于c++ - 如何将 SHFileOperation() 与 CString 路径一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52440995/