[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