简体   繁体   English

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

[英]What's the difference between CMD and PowerShell when deleting a file in Windows?

When I run a commandline program (which internally deletes a log file) from CMD prompt, it's working as expected. 当我从CMD提示符运行命令行程序(内部删除日志文件)时,它正在按预期工作。

But the same command when run in a PowerShell prompt is not deleting the log file. 但是,在PowerShell提示符下运行时,相同的命令不会删除日志文件。 The command is run successfully except for the log file deletion. 除删除日志文件外,该命令已成功运行。 There is no error or exception thrown from the PowerShell prompt. PowerShell提示没有引发任何错误或异常。

How does PowerShell differ from a CMD prompt in the Windows environment with respect to file handling, in this case it's deleting a file? 在文件处理方面,PowerShell与Windows环境中的CMD提示有何不同?在这种情况下,PowerShell正在删除文件?

Note: Both the CMD prompt and PowerShell are run as Administrator. 注意:CMD提示符和PowerShell均以管理员身份运行。

The source code of the program looks like this: 该程序的源代码如下所示:

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);

remove() is the function which deletes the file. remove()是删除文件的函数。

Update : I have tried changing remove() to DeleteFile() , the behavior is still same. 更新 :我尝试将remove()更改为DeleteFile() ,其行为仍然相同。

Update 2 : I have found the root cause. 更新2 :我找到了根本原因。 PowerShell is returning an absolute path whereas the CMD prompt is returning a relative path. PowerShell返回绝对路径,而CMD提示符返回相对路径。 This is not part of the above code snippet. 这不是上面的代码片段的一部分。

Now I need to find whether the path is relative or not. 现在,我需要查找路径是否相对。 There is a Windows function, PathIsRelative(), but it takes LPCWSTR as input and again some conversion is required. 有一个Windows函数PathIsRelative(),但是它将LPCWSTR作为输入,再次需要进行一些转换。

My psychic powers tell me that the file name has non-ASCII characters in it and the error in the failing case is "file not found." 我的灵通能力告诉我,文件名中包含非ASCII字符,并且失败情况下的错误是“找不到文件”。

In the code, you copy wide characters into regular char s. 在代码中,将宽字符复制到常规char For anything outside of ASCII, this won't do what you want. 对于ASCII以外的任何内容,这都不会做您想要的。

Your code sample doesn't show how you get the source string or strPath. 您的代码示例未显示如何获取源字符串或strPath。

It's possible that, when you enter the search string in the CMD case, it's got some non-ASCII characters that are representable in the current code page, and those values are copied to wide characters and then back without harm, and the remove works. 在CMD情况下输入搜索字符串时,可能会得到一些在当前代码页中可表示的非ASCII字符,然后将这些值复制为宽字符,然后无损地返回,并且删除有效。

When you enter it in PowerShell, you probably get UTF-16 encoded text. 在PowerShell中输入它时,可能会得到UTF-16编码的文本。 When you copy those values back to regular char s, you're not getting the same string, so the remove probably fails with "file not found." 当您将这些值复制回常规char ,不会获得相同的字符串,因此删除可能会失败,并显示“找不到文件”。

Don't do this: 不要这样做:

string cFileName(wsFilename.begin(), wsFilename.end());

Work with wide strings consistently, without any conversions. 始终使用宽字符串,无需任何转换。 If you must convert between wide and narrow strings, you must know the encoding and actually transcode the data, not just copy it. 如果必须在宽字符串和窄字符串之间进行转换,则必须知道编码并实际对数据进行转码,而不仅仅是复制数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM