Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C DeleteFile()或unlink()调用成功,但不';不要删除文件_C_Windows_Winapi_Win32 Process - Fatal编程技术网

C DeleteFile()或unlink()调用成功,但不';不要删除文件

C DeleteFile()或unlink()调用成功,但不';不要删除文件,c,windows,winapi,win32-process,C,Windows,Winapi,Win32 Process,我面临着这个奇怪的问题。 在我的代码中调用了删除文件的API。此调用将删除文件并在非windows平台上成功。在windows上,它会成功(返回0),但不会删除该文件 // Code to create the file int create_file(const char* path) { HANDLE osfh; /* OS handle of opened file */ DWORD fileaccess;

我面临着这个奇怪的问题。 在我的代码中调用了删除文件的API。此调用将删除文件并在非windows平台上成功。在windows上,它会成功(返回0),但不会删除该文件

// Code to create the file
int create_file(const char* path)
{
  HANDLE osfh;                            /* OS handle of opened file */
  DWORD fileaccess;                       /* OS file access (requested) */
  DWORD fileshare;                        /* OS file sharing mode */
  DWORD filecreate;                       /* OS method of opening/creating */
  DWORD fileattrib;                       /* OS file attribute flags */
  SECURITY_ATTRIBUTES SecurityAttributes;


  SecurityAttributes.nLength= sizeof(SecurityAttributes);
  SecurityAttributes.lpSecurityDescriptor= NULL;
  SecurityAttributes.bInheritHandle= !(oflag & _O_NOINHERIT);



 fileaccess= GENERIC_WRITE;
 fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
 filecreate= CREATE_NEW; 


 if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes, 
 filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE)
 {
   // error handling
 }

}

//Code to delete the file - 
int remove_file (const char* name)
{
  if ((err = unlink(name)) == -1)
  { //Error handling }
}
为了进行实验,我添加了一个循环来重复调用相同的API。在第二次迭代中,我得到了一个权限被拒绝的错误,错误代码=13。尽管在文件上设置了读/写属性,并且程序具有访问该文件的完全权限

// Code to create the file
int create_file(const char* path)
{
  HANDLE osfh;                            /* OS handle of opened file */
  DWORD fileaccess;                       /* OS file access (requested) */
  DWORD fileshare;                        /* OS file sharing mode */
  DWORD filecreate;                       /* OS method of opening/creating */
  DWORD fileattrib;                       /* OS file attribute flags */
  SECURITY_ATTRIBUTES SecurityAttributes;


  SecurityAttributes.nLength= sizeof(SecurityAttributes);
  SecurityAttributes.lpSecurityDescriptor= NULL;
  SecurityAttributes.bInheritHandle= !(oflag & _O_NOINHERIT);



 fileaccess= GENERIC_WRITE;
 fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
 filecreate= CREATE_NEW; 


 if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes, 
 filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE)
 {
   // error handling
 }

}

//Code to delete the file - 
int remove_file (const char* name)
{
  if ((err = unlink(name)) == -1)
  { //Error handling }
}
然后我调用了而不是unlink()API。令我惊讶的是,我看到了相同的结果,调用成功,即返回1,但文件没有被物理删除

我通过unlocker实用程序进行了检查,除了试图删除该文件的程序外,没有其他程序正在访问该文件

有人知道还有什么问题吗

Edit1: 只是为了确保文件在删除时未被打开。我在创建文件时保存了句柄,并试图在删除文件之前关闭,但出现错误“'UNOPENED'(错误代码:9-错误的文件描述符)”。因此,我得出结论,文件在删除时未打开

Edit2 根据要求,以下是用于创建和删除文件的简化版本代码

// Code to create the file
int create_file(const char* path)
{
  HANDLE osfh;                            /* OS handle of opened file */
  DWORD fileaccess;                       /* OS file access (requested) */
  DWORD fileshare;                        /* OS file sharing mode */
  DWORD filecreate;                       /* OS method of opening/creating */
  DWORD fileattrib;                       /* OS file attribute flags */
  SECURITY_ATTRIBUTES SecurityAttributes;


  SecurityAttributes.nLength= sizeof(SecurityAttributes);
  SecurityAttributes.lpSecurityDescriptor= NULL;
  SecurityAttributes.bInheritHandle= !(oflag & _O_NOINHERIT);



 fileaccess= GENERIC_WRITE;
 fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
 filecreate= CREATE_NEW; 


 if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes, 
 filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE)
 {
   // error handling
 }

}

//Code to delete the file - 
int remove_file (const char* name)
{
  if ((err = unlink(name)) == -1)
  { //Error handling }
}
Edit3 正如Joachim Pileborg和icabod所指出的那样,
DeleteFile()
不会删除仍然打开的文件。按照Remy Lebeau的建议,使用process explorer。当我从process explorer文件中关闭该文件时,我发现该文件的一个句柄确实打开了,就像一个符咒一样被删除:)


我在Edit1中也提到,当我试图关闭文件时,出现了一个错误。之所以发生这种情况,是因为我从
createfile()
获取的文件描述符不是createfile()API返回的实际句柄,而是一个逻辑映射句柄,因为底层代码复杂,无法支持其他非windows平台。无论如何,现在我理解了问题的根本原因,但我希望如果将具有打开句柄的文件传递给
DeleteFile()
API,那么它应该在第一次尝试中失败,而不是成功,并等待打开句柄关闭。

假设您调用
Createfile
函数,然后稍后调用您的
remove\u文件
函数。。。您仍然有一个文件的句柄打开。WinAPI函数
CreateFile
,如果成功,将保持文件上的句柄打开。在提供的代码中,不关闭该句柄

从以下文件:

DeleteFile函数在关闭时标记要删除的文件。因此,在关闭文件的最后一个句柄之前,不会删除文件。后续调用CreateFile以打开文件失败,错误为\u访问被拒绝

我猜您仍然有一个句柄处于打开状态,当您关闭该句柄时,文件将被删除


但是,您的示例代码不完整,因此很难判断。

您说“除了试图删除此文件的程序外,没有其他程序正在访问该文件”。这是否意味着您已经在程序中打开了文件(例如,
open
fopen
CreateFile
)?然后不,它将不会从磁盘上删除,因为您的程序仍然打开它。如果你先关闭文件,然后删除它,它应该会起作用。如果人们觉得这个问题不值得问,我觉得很奇怪,在否决投票的同时也这么说。这个问题怎么了?@JoachimPileborg如果文件仍然打开,不应该
DeleteFile
返回false吗?@Rahul发布一些代码。顺便说一句,
\u unlink
除了调用
DeleteFile
没有什么作用,所以如果
\u unlink
失败,
DeleteFile
也会失败,这其实是正常的。当
DeleteFile
失败时,
GetLastError()
返回什么?@MichaelWalz这取决于是否设置了
FILE\u SHARE\u DELETE
标志(我想我不是Windows API的老家)。但是现在我同意是时候看看了。你可以使用SysInternals Process Explorer这样的工具来找出谁拥有被删除文件的打开句柄。是的,PE非常有用。我想指出的是,你不应该用它来强制关闭把手——因为,这可能会非常糟糕。最好确保您关闭所有自己的句柄,如果您担心其他人访问该文件,请不要使用
SHARED
access打开它。