如何将 SHFileOperation() 与 CString 路径一起使用
How to use SHFileOperation() with CString paths
我正在尝试将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\* "),
firstPathDest("C:\ORTIM-Daten\a5Pc 2.0.3\"),
lastPartDest("Documents\"),
_folderNameDest("a6_töüst-Oa5Z.OZS-CI5O5235 ");
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 ")*/;
s.pFrom = cstrTemp /*_TEXT("C:\ORTIM-Daten\a5Pc 2.0.3\Temp\a6_töüst-Oa5Z.OZS-CI5O5235\Documents\* ")*/;
SHFileOperation(&s);
当我直接使用CString
时,复制操作不起作用,但是当我使用_TEXT()
宏(如注释中所示(在结构中分配LPCWSTR
成员时,一切正常。
编辑 1
在源路径和目标路径的变体中,代码都会编译。
在此变体中,代码编译并执行复制操作:
s.pTo = _TEXT("C:\ORTIM-Daten\a5Pc 2.0.3\Documents\a6_töüst-Oa5Z.OZS-CI5O5235 ");
s.pFrom = _TEXT("C:\ORTIM-Daten\a5Pc 2.0.3\Temp\a6_töüst-Oa5Z.OZS-CI5O5235\Documents\* ");
在我实际需要的另一个变体中,代码也可以编译,但不会发生复制操作:
s.pTo = cstrTempDest;
s.pFrom = cstrTemp;
>SHFILEOPSTRUCT
需要以两个NUL 字符结尾的字符串,但根据定义,NUL 终止的字符串以1结尾,并且任何其他 NUL 字符都将被不接受显式长度参数CString
方法忽略。
您可以通过手动添加一个来强制双 NULL:
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 ");
// +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
返回值。
用户 msp0815 关于创建双空结尾 CString 的答案解决了您的问题。
// strings must be double-null terminated
CString from(cstrTemp + (TCHAR)' ');
PCZZTSTR szzFrom= from;
s.pFrom= szzFrom;
CString dest(cstrTempDest + (TCHAR)' ');
PCZZTSTR szzDest= dest;
s.pTo= szzDest;
我通常不会经常使用 LPCWSTR,但这是我的想法:
CString TestCSTR = "Hello world";
LPCWSTR TestLPC;
TestLPC = (LPCWSTR)_TEXT(TestCSTR.GetString());
事实上,它按预期工作,变量TestLPC包含"Hello world",或者更准确地说,是指向它的长指针。应该可以在没有后果的情况下删除_TEXT但我不确定,顺便说一句,结果是一样的。
- 如何将更多文件夹添加到c++include路径
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- C++A*算法并不总是在路径中具有目标节点
- 在C++中使用Cstring反转字符串
- 从函数角度看ID到文件路径的内部与外部映射
- boost xml parsingl将xml的路径作为变量发送
- 对于MacOS上的G++,如何添加默认的include目录/usr/local/include和默认的库搜索路径/usr
- 如何使用cppcheck处理半相对包含路径
- 在C++中设置基于操作系统的文件路径
- 基于编译器选项的编译二进制路径
- 按边长度递归搜索图中所有可行路径
- 使用变量值作为 PlaySound 中的路径
- 如何转换真实路径 CString c++
- 从 GUID 获取 USB 卷路径
- 查找 GCD:并非所有控制路径都返回值
- C++17 文件系统::remove_all 带有通配符路径
- 在带有尾部斜杠的路径上返回 std::filesystem::create_directories() 的值
- 获取当前正在运行的 exe 名称(不是路径)
- 如何从 Skia 路径几何体中获取网格?
- 如何将 SHFileOperation() 与 CString 路径一起使用