user631175
user631175

Reputation:

Python - Downloading a .exe file from the internet

In the process of creating an auto-updater for my program, and I'm having trouble successfully downloading an .exe file.

What I was doing was something like this:

import urllib

url = '--insert-url--'

f = urllib.urlopen(url)
file = f.read()
f.close
f2 = open('download.exe', 'w')
f2.write(file)
f2.close

I encountered no errors while downloading, but when I try to run the execution, I get the following error:

The version of this file is not compatable with the version of Windows you're running. Check your computer's system information to see whether you need an x86(32-bit) or an x64 (64-bit) version of the program, and then contact the software publisher.

I uploaded the execution myself and it worked fine before.

I also tried some various other methods for downloading that I found, which resulted in the same error, and I also tried uploading to different sites to make sure that wasn't it.

Is there a special way I need to do this?

EDIT:

I did some further testing with the download. I ran the program (I'm using what Spencer posted now) on a different computer -- a 32-bit system. (Mine is a 64-bit.) I don't get the error on that computer, but when I run the program, the command line comes up, as it is a command-line style .exe that I'm using as my test download, but the blinking white entry bar thing just bounces all over the place before I have to end the program, so something is obviously getting corrupted.

Also, would the downloading process be possible with a Batch file? This would almost be easier as the program is going to have to restart to begin using the new update anyway, as it is using an entirely new .exe. (I'm going to use py2exe for making the program an .exe.)

Upvotes: 4

Views: 12926

Answers (3)

9301293
9301293

Reputation: 511

So, I think maybe you were having a different problem.

My specs: Python3.X, installed via Homebrew. Using Python's urllib.request module, as it is the currently supported one.

I think that you were downloading a html page, which re-routed you to the download link. This is especially the case if you are trying to download from link. Many websites, and servers, have you click a button, which will provide a different url to download from.

For instance, if you try to download any Microsoft link, like the FCIV checksum program, the download button actually routes you through a different url.


Answer

My suggestion is that you load up the byte file you downloaded in your original answer as a .htm/l file. From here, you can try to find a url with an application extension;

For instance, if you stick with the FCIV example, you will download something that give the same error:

The version of this file is not compatable with the version of Windows you're running. Check your computer's system information to see whether you need an x86(32-bit) or an x64 (64-bit) version of the program, and then contact the software publisher.

On closer inspection, if you load this file up as a .htm/l file, you can search for the x86 string and discover that it is on a url with actual name https://download.microsoft.com/download/c/f/4/cf454ae0-a4bb-4123-8333-a1b6737712f7/Windows-KB841290-x86-ENU.exe After which, if you try your download in the OP with this new url/https request, you will actually have a .exe that is correct.


EDIT Sorry, this answer may only apply to Python3.X in the year 2017. The answer is a little late to the original question asked 6 years ago. Also, the other answers and comments about the b flag in file writing is correct. The file should be opened with wb permissions.

Upvotes: 0

Spencer Rathbun
Spencer Rathbun

Reputation: 14910

According to the official python docs for urllib:

One caveat: the read() method, if the size argument is omitted or negative, may not read until the end of the data stream; there is no good way to determine that the entire stream from a socket has been read in the general case.

an alternative from the same library would be

import urllib

url = '--insert-url--' 

filename = 'download.exe'  
urllib.urlretrieve(url, filename)

Upvotes: 3

David Wolever
David Wolever

Reputation: 154644

I suspect that you need to include the b (binary) flag in your call to open:

import urllib

url = '--insert-url--'

f = urllib.urlopen(url)
file = f.read()
f.close()
f2 = open('download.exe', 'wb')
f2.write(file)
f2.close()

Also, you've omitted the parents in your calls to .close(). Not sure if that's a problem with your understanding or your example, but I've fixed it in the code above.

Also, if your .exe is big, you may want to write it to the file as you download it (currently you're reading the entire thing into memory). That would look something like:

f2 = open("download.exe", "wb")
try:
    while True:
        data = f.read(4096)
        if not data:
            break
        f2.write(data)
finally:
    f.close()
    f2.close()

Upvotes: 3

Related Questions