cor*_*ing 2 c++ powershell cmd command-line-interface delete-file
当我从 CMD 提示符运行命令行程序(在内部删除日志文件)时,它按预期工作。
但是在 PowerShell 提示符下运行的相同命令不会删除日志文件。除删除日志文件外,该命令运行成功。PowerShell 提示符不会抛出任何错误或异常。
在文件处理方面,PowerShell 与 Windows 环境中的 CMD 提示有何不同,在这种情况下是删除文件?
注意:CMD 提示符和 PowerShell 都以管理员身份运行。
该程序的源代码如下所示:
WIN32_FIND_DATA fd;
LPCWSTR search_path_wstr = ws.c_str();
HANDLE hFind = ::FindFirstFile(search_path_wstr, &fd);
wstring wsFilename(fd.cFileName);
string cFileName(wsFilename.begin(), wsFilename.end());
string absoluteFilename = strPath + "\\" + cFileName;
const char *filename = absoluteFilename.c_str();
remove(filename);
Run Code Online (Sandbox Code Playgroud)
remove() 是删除文件的函数。
更新:我尝试更改remove()为DeleteFile(),行为仍然相同。
更新 2:我找到了根本原因。PowerShell 返回绝对路径,而 CMD 提示返回相对路径。这不是上述代码片段的一部分。
现在我需要找出路径是否是相对的。有一个 Windows 函数 PathIsRelative(),但它需要 LPCWSTR 作为输入,并且再次需要一些转换。
我的通灵能力告诉我,文件名中包含非 ASCII 字符,失败案例中的错误是“找不到文件”。
在代码中,您将宽字符复制到常规chars 中。对于 ASCII 之外的任何内容,这都不会满足您的需求。
您的代码示例未显示如何获取源字符串或 strPath。
有可能,当您在 CMD 案例中输入搜索字符串时,它有一些可在当前代码页中表示的非 ASCII 字符,并且这些值被复制到宽字符然后返回而不会造成任何伤害,并且删除有效。
当您在 PowerShell 中输入它时,您可能会得到 UTF-16 编码的文本。当您将这些值复制回常规chars 时,您不会得到相同的字符串,因此删除可能会因“找不到文件”而失败。
不要这样做:
string cFileName(wsFilename.begin(), wsFilename.end());
Run Code Online (Sandbox Code Playgroud)
一致地使用宽字符串,无需任何转换。如果您必须在宽字符串和窄字符串之间进行转换,您必须知道编码并对数据进行实际转码,而不仅仅是复制它。