[Qt-interest] QFile::copy() fails on Windows Vista if the source is in resources (Was Re: QFile::remove() fails on Windows Vista)

Yevgen Muntyan muntyan at fastmail.fm
Tue Jun 23 19:52:38 CEST 2009


QTemporaryFile::close() doesn't close it? I believe Qt calls close() before
renaming.


Constantin Makshin wrote:
> I guess I've found the source of this problem -- QFile::copy() uses  
> temporary file when native API can't do the work (and that happens because  
> native APIs don't know about Qt reources), and since QTemporaryFile object  
> doesn't close its file until it (object) is destroyed, any attempt to  
> delete it (file) fails.
>
> As a workaround, you can use something like this:
>
> QFile file(":/deltest.pro"),
>        destFile("copycopy.txt");
> if (srcFile.open(QIODevice::ReadOnly) &&
>      destFile.open(QIODevice::WriteOnly))
> {
>      QByteArray data = file.readAll();
>      destFile.write(data);
> }
> file.close();
> destFile.close();
>
> On Tue, 23 Jun 2009 08:05:14 +0400, Yevgen Muntyan <muntyan at fastmail.fm>  
> wrote:
>   
>> Hey,
>>
>> I tried simple QFile::rename(), it works fine for regular files. My  
>> program copies a file from
>> resources and apparently that hits an unlucky code path.
>>
>> DeleteFile fails because the file is held by someone else. I can't  
>> delete the file while the application
>> is sitting in debugger right before DeleteFile call. DeleteFile returns  
>> 0, and GetLastError is 32.
>> Trying to delete file in cmd.exe I get "The process cannot access the  
>> file because it is being used
>> by another process." After I let the program run further (and after  
>> QFile::rename() fails), I can
>> delete the file without problems, with or without "\\?\" prefix. What I  
>> said earlier about the prefix
>> was wrong, I simply tried to delete the file while the program was  
>> stopped.
>>
>> The following is a complete test case which reproduces my problem (you  
>> need to add a resource
>> file which includes some file, deltest.pro in this code):
>>
>> #include <QtGui>
>>
>> int main(int argc, char *argv[])
>> {
>>     QApplication app(argc, argv);
>>     QFile file(":/deltest.pro");
>>     if (file.copy("copycopy.txt"))
>>         QMessageBox::information(0, "yay!", "yay!");
>>     else
>>         QMessageBox::critical(0, "oops!", file.errorString());
>>     return 0;
>> }
>>
>> It gives me "Cannot create copycopy.txt for output" (it's lying, the  
>> error message is overwritten inside
>> QFile::copy).
>>
>> Best regards,
>> Yevgen
>>
>> Constantin Makshin wrote:
>>     
>>> "\\?\" prefix is used to extend the maximum path length from 259 to  
>>> ~32000  characters. Could you call DeleteFileW(L"\\?\<path>"), where  
>>> <path> is the  absolute path to your temporary file with backslashes as  
>>> path delimiters,  directly and see what it returns?
>>>
>>> On Mon, 22 Jun 2009 21:00:48 +0400, Yevgen Muntyan  
>>> <muntyan at fastmail.fm>  wrote:
>>>
>>>       
>>>> Yevgen Muntyan wrote:
>>>>
>>>>         
>>>>> Hey,
>>>>>
>>>>> I have a problem with QFile::rename: it fails when it tries to  
>>>>> remove  the
>>>>> temporary file it uses, because DeleteFileW() fails inside
>>>>> QFSFileEngine::remove(). My code is roughly the following:
>>>>>
>>>>> QFile source(":/gap/ggap.g");
>>>>> source.copy("C:/Users/muntyan/AppData/Local/Temp/ggap-000025cb/ggap.g")
>>>>>
>>>>> The copy() call here fails.
>>>>> "C:/Users/muntyan/AppData/Local/Temp/ggap-000025cb" directory is  
>>>>> created
>>>>> with QDir::mkdir(), and I do have permissions to delete files from  
>>>>> it,  and I
>>>>> can delete files from it in explorer. The temporary files   
>>>>> qt_temp.XXXXXX are
>>>>> not read-only, so DeleteFile() isn't supposed to fail. But it does!
>>>>>
>>>>>
>>>>>           
>>>> I found out that Qt calls DeleteFile() on some funny long version of  
>>>> the
>>>> filename, namely it passes
>>>> the following string to DeleteFile:
>>>>
>>>> \\?\c:\Users\muntyan\AppData\Local\Temp\ggap-00002d22\qt_temp.Za5308
>>>>
>>>> it prepends \\?\ in QFSFileEnginePrivate::longFileName(). DeleteFile()
>>>> doesn't fail if I call it on
>>>> the filename without that prefix. Ideas?
>>>>
>>>> Thanks,
>>>> Yevgen
>>>>         
>
>   




More information about the Qt-interest-old mailing list