在 Windows 中删除文件时,CMD 和 PowerShell 有什么区别?

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 作为输入,并且再次需要一些转换。

Adr*_*thy 5

我的通灵能力告诉我,文件名中包含非 ASCII 字符,失败案例中的错误是“找不到文件”。

在代码中,您将宽字符复制到常规chars 中。对于 ASCII 之外的任何内容,这都不会满足您的需求。

您的代码示例未显示如何获取源字符串或 strPath。

有可能,当您在 CMD 案例中输入搜索字符串时,它有一些可在当前代码页中表示的非 ASCII 字符,并且这些值被复制到宽字符然后返回而不会造成任何伤害,并且删除有效。

当您在 PowerShell 中输入它时,您可能会得到 UTF-16 编码的文本。当您将这些值复制回常规chars 时,您不会得到相同的字符串,因此删除可能会因“找不到文件”而失败。

不要这样做:

string cFileName(wsFilename.begin(), wsFilename.end());
Run Code Online (Sandbox Code Playgroud)

一致地使用宽字符串,无需任何转换。如果您必须在宽字符串和窄字符串之间进行转换,您必须知道编码并对数据进行实际转码,而不仅仅是复制它。