File::startAsProcess Failing for a file I just downloaded


#1

Hey there,

I have a bunch of code that works on the mac but fails in windows and I’m not sure how to resolve it.

I am downloading a file from the web to the temp directory, and in the windows case, trying to run it. I think the call is failing in windows because the OS wont allow the file to be used by my program and run at the same time. The problem is, as neither File or OutputStream have any concept of close, I can’t figure out to modify, or even StartAsProcess() a file I have just written.

Here is the code, it’s broken into two functions – a Thread::Run that does the download, and then another function that grabs the file and attempts to open it once the download has succeeded.

Here is the download…


void WebDownloadThread::run()
{
    bool failed = false;
    m_downloadProgress = 0.0;

    m_stateLock.enter();
    m_state = Busy;
    m_stateLock.exit();

    m_dataLock.enter();

    InputStream* input = m_url.createInputStream(m_isPost,
                                                 NULL,
                                                 NULL);

	String filename = m_url.getSubPath();
	filename = filename.substring(filename.lastIndexOfChar('/') + 1);
	filename = "MyApp" +  filename;
    m_downloadedFile = File::createTempFile(filename);
    

    if(input){
        int total = input->getTotalLength();
        FileOutputStream* output = m_downloadedFile.createOutputStream(0x8000);

        while(!input->isExhausted()){
            output->writeFromInputStream(*input, 0x8000);
            int position = input->getPosition();
            m_progressLock.enter();
            m_downloadProgress = (float) position / (float) total;
            m_progressLock.exit();
        }
        output->flush();
        m_downloadProgress = 1.0;
    }
    else
        failed = true;

    m_dataLock.exit();

    m_stateLock.enter();
    if(failed)
        m_state = Failed;
    else
        m_state = Succeeded;
    m_stateLock.exit();
}

And Here is the open:

void SoftwareUpdateManager::finishSoftwareUpdate(){
    if(m_softwareUpdateDownloadThread->getState() != WebDownloadThread::Succeeded)
        return;

    File downloadedFile = m_softwareUpdateDownloadThread->getDownloadedFile();
	if(downloadedFile.startAsProcess())
	{
		LOG_DEBUG("Succesffully launched new installer\n");
	}
	else
	{
                // land up here every time in windows
		LOG_DEBUG("Failed to launch new installer\n");
	}
}

The downloaded file will open from the Explorer only after my program quits, with the complaint that another program is using the file. That is why I think it has something to do with me not explicitely closing it. Is there a way can force my variable to close the file?

Thanks Jules,


#2

Yes - you can delete the stream, rather than just letting all your objects leak!!

Yes - you can delete the stream, rather than just letting all your objects leak!!


#3

Ok that makes sense…

This may be incredibly naive of me, but as the documentation doesn’t make any mention that it’s caller’s responsibility to delete the stream, I assumed the pointer was a reference to an object controlled in the File class.

This change is going to have greater repercussions on my code - If juce returns a pointer, should i always assume it’s my responsibility to delete the returned object?


#4

Typically if I see a word like new or create in a method name, I’d tend to assume that what I’m getting back is always going to be my own instance of an object.

From a JUCE perspective, I’ve found the documentation tends to be explicit when one shouldn’t take ownership of a returned object or memory block.


#5

I do always add some comments where I think it’s non-obvious what to do with the pointer. I guess for that method I must have assumed it was obvious, because you wouldn’t expect the URL object to keep track of all the streams that it creates or to know when you’re finished with them. But fair enough, I should probably have added a comment just to avoid confusion.


#6

Thanks for the help. In retrospect I feel silly for assuming the stream wasn’t mine to delete That said, the comment addition couldn’t hurt :-).

I think JUCE is a marvelous library by the way, thanks for all the hard work :slight_smile: