Skip to content

Instantly share code, notes, and snippets.

@mmozeiko
Last active July 2, 2024 19:21
Show Gist options
  • Save mmozeiko/7f3162ec2988e81e56d5c4e22cde9977 to your computer and use it in GitHub Desktop.
Save mmozeiko/7f3162ec2988e81e56d5c4e22cde9977 to your computer and use it in GitHub Desktop.
Download MSVC compiler/linker & Windows SDK without installing full Visual Studio

This downloads standalone MSVC compiler, linker & other tools, also headers/libraries from Windows SDK into portable folder, without installing Visual Studio. Has bare minimum components - no UWP/Store/WindowsRT stuff, just files & tools for native desktop app development.

Run py.exe portable-msvc.py and it will download output into msvc folder. By default it will download latest available MSVC & Windows SDK - currently v14.40.33807 and v10.0.26100.0.

You can list available versions with py.exe portable-msvc.py --show-versions and then pass versions you want with --msvc-version and --sdk-version arguments.

To use cl.exe/link.exe first run setup_TARGET.bat - after that PATH/INCLUDE/LIB env variables will be updated to use all the tools as usual. You can also use clang-cl.exe with these includes & libraries.

To use clang-cl.exe without running setup.bat, pass extra /winsysroot msvc argument (msvc is folder name where output is stored).

#!/usr/bin/env python3
import io
import os
import sys
import stat
import json
import shutil
import hashlib
import zipfile
import tempfile
import argparse
import subprocess
import urllib.error
import urllib.request
from pathlib import Path
OUTPUT = Path("msvc") # output folder
DOWNLOADS = Path("downloads") # temporary download files
# NOTE: not all host & target architecture combinations are supported
DEFAULT_HOST = "x64"
ALL_HOSTS = "x64 x86 arm64".split()
DEFAULT_TARGET = "x64"
ALL_TARGETS = "x64 x86 arm arm64".split()
MANIFEST_URL = "https://aka.ms/vs/17/release/channel"
MANIFEST_PREVIEW_URL = "https://aka.ms/vs/17/pre/channel"
ssl_context = None
def download(url):
with urllib.request.urlopen(url, context=ssl_context) as res:
return res.read()
total_download = 0
def download_progress(url, check, name, filename):
fpath = DOWNLOADS / filename
if fpath.exists():
data = fpath.read_bytes()
if hashlib.sha256(data).hexdigest() == check.lower():
print(f"\r{name} ... OK")
return data
global total_download
with fpath.open("wb") as f:
data = io.BytesIO()
with urllib.request.urlopen(url, context=ssl_context) as res:
total = int(res.headers["Content-Length"])
size = 0
while True:
block = res.read(1<<20)
if not block:
break
f.write(block)
data.write(block)
size += len(block)
perc = size * 100 // total
print(f"\r{name} ... {perc}%", end="")
print()
data = data.getvalue()
digest = hashlib.sha256(data).hexdigest()
if check.lower() != digest:
exit(f"Hash mismatch for f{pkg}")
total_download += len(data)
return data
# super crappy msi format parser just to find required .cab files
def get_msi_cabs(msi):
index = 0
while True:
index = msi.find(b".cab", index+4)
if index < 0:
return
yield msi[index-32:index+4].decode("ascii")
def first(items, cond):
return next((item for item in items if cond(item)), None)
### parse command-line arguments
ap = argparse.ArgumentParser()
ap.add_argument("--show-versions", action="store_true", help="Show available MSVC and Windows SDK versions")
ap.add_argument("--accept-license", action="store_true", help="Automatically accept license")
ap.add_argument("--msvc-version", help="Get specific MSVC version")
ap.add_argument("--sdk-version", help="Get specific Windows SDK version")
ap.add_argument("--preview", action="store_true", help="Use preview channel for Preview versions")
ap.add_argument("--target", default=DEFAULT_TARGET, help=f"Target architectures, comma separated ({','.join(ALL_TARGETS)})")
ap.add_argument("--host", default=DEFAULT_HOST, help=f"Host architecture", choices=ALL_HOSTS)
args = ap.parse_args()
host = args.host
targets = args.target.split(',')
for target in targets:
if target not in ALL_TARGETS:
exit(f"Unknown {target} target architecture!")
### get main manifest
URL = MANIFEST_PREVIEW_URL if args.preview else MANIFEST_URL
try:
manifest = json.loads(download(URL))
except urllib.error.URLError as err:
import ssl
if isinstance(err.args[0], ssl.SSLCertVerificationError):
# for more info about Python & issues with Windows certificates see https://stackoverflow.com/a/52074591
print("ERROR: ssl certificate verification error")
try:
import certifi
except ModuleNotFoundError:
print("ERROR: please install 'certifi' package to use Mozilla certificates")
print("ERROR: or update your Windows certs, see instructions here: https://woshub.com/updating-trusted-root-certificates-in-windows-10/#h2_3")
exit()
print("NOTE: retrying with certifi certificates")
ssl_context = ssl.create_default_context(cafile=certifi.where())
manifest = json.loads(download(URL))
else:
raise
### download VS manifest
ITEM_NAME = "Microsoft.VisualStudio.Manifests.VisualStudioPreview" if args.preview else "Microsoft.VisualStudio.Manifests.VisualStudio"
vs = first(manifest["channelItems"], lambda x: x["id"] == ITEM_NAME)
payload = vs["payloads"][0]["url"]
vsmanifest = json.loads(download(payload))
### find MSVC & WinSDK versions
packages = {}
for p in vsmanifest["packages"]:
packages.setdefault(p["id"].lower(), []).append(p)
msvc = {}
sdk = {}
for pid,p in packages.items():
if pid.startswith("Microsoft.VisualStudio.Component.VC.".lower()) and pid.endswith(".x86.x64".lower()):
pver = ".".join(pid.split(".")[4:6])
if pver[0].isnumeric():
msvc[pver] = pid
elif pid.startswith("Microsoft.VisualStudio.Component.Windows10SDK.".lower()) or \
pid.startswith("Microsoft.VisualStudio.Component.Windows11SDK.".lower()):
pver = pid.split(".")[-1]
if pver.isnumeric():
sdk[pver] = pid
if args.show_versions:
print("MSVC versions:", " ".join(sorted(msvc.keys())))
print("Windows SDK versions:", " ".join(sorted(sdk.keys())))
exit(0)
msvc_ver = args.msvc_version or max(sorted(msvc.keys()))
sdk_ver = args.sdk_version or max(sorted(sdk.keys()))
if msvc_ver in msvc:
msvc_pid = msvc[msvc_ver]
msvc_ver = ".".join(msvc_pid.split(".")[4:-2])
else:
exit(f"Unknown MSVC version: f{args.msvc_version}")
if sdk_ver in sdk:
sdk_pid = sdk[sdk_ver]
else:
exit(f"Unknown Windows SDK version: f{args.sdk_version}")
print(f"Downloading MSVC v{msvc_ver} and Windows SDK v{sdk_ver}")
### agree to license
tools = first(manifest["channelItems"], lambda x: x["id"] == "Microsoft.VisualStudio.Product.BuildTools")
resource = first(tools["localizedResources"], lambda x: x["language"] == "en-us")
license = resource["license"]
if not args.accept_license:
accept = input(f"Do you accept Visual Studio license at {license} [Y/N] ? ")
if not accept or accept[0].lower() != "y":
exit(0)
OUTPUT.mkdir(exist_ok=True)
DOWNLOADS.mkdir(exist_ok=True)
### download MSVC
msvc_packages = [
f"microsoft.visualcpp.dia.sdk",
f"microsoft.vc.{msvc_ver}.crt.headers.base",
f"microsoft.vc.{msvc_ver}.crt.source.base",
f"microsoft.vc.{msvc_ver}.asan.headers.base",
f"microsoft.vc.{msvc_ver}.premium.tools.{host}.base.base",
f"microsoft.vc.{msvc_ver}.pgo.headers.base",
]
for target in targets:
msvc_packages += [
f"microsoft.vc.{msvc_ver}.tools.host{host}.target{target}.base",
f"microsoft.vc.{msvc_ver}.tools.host{host}.target{target}.res.base",
f"microsoft.vc.{msvc_ver}.crt.{target}.desktop.base",
f"microsoft.vc.{msvc_ver}.crt.{target}.store.base",
f"microsoft.vc.{msvc_ver}.crt.redist.{target}.base",
f"microsoft.vc.{msvc_ver}.premium.tools.host{host}.target{target}.base",
f"microsoft.vc.{msvc_ver}.pgo.{target}.base",
]
if target in ["x86", "x64"]:
msvc_packages += [
f"microsoft.vc.{msvc_ver}.asan.{target}.base",
]
for pkg in msvc_packages:
if pkg not in packages:
continue
p = first(packages[pkg], lambda p: p.get("language") in (None, "en-US"))
for payload in p["payloads"]:
filename = payload["fileName"]
download_progress(payload["url"], payload["sha256"], pkg, filename)
with zipfile.ZipFile(DOWNLOADS / filename) as z:
for name in z.namelist():
if name.startswith("Contents/"):
out = OUTPUT / Path(name).relative_to("Contents")
out.parent.mkdir(parents=True, exist_ok=True)
out.write_bytes(z.read(name))
### download Windows SDK
sdk_packages = [
f"Windows SDK for Windows Store Apps Tools-x86_en-us.msi",
f"Windows SDK for Windows Store Apps Headers-x86_en-us.msi",
f"Windows SDK for Windows Store Apps Headers OnecoreUap-x86_en-us.msi",
f"Windows SDK for Windows Store Apps Libs-x86_en-us.msi",
f"Windows SDK OnecoreUap Headers x86-x86_en-us.msi",
f"Windows SDK Desktop Headers x86-x86_en-us.msi",
f"Universal CRT Headers Libraries and Sources-x86_en-us.msi",
]
for target in targets:
sdk_packages += [
f"Windows SDK Desktop Libs {target}-x86_en-us.msi",
]
with tempfile.TemporaryDirectory(dir=DOWNLOADS) as d:
dst = Path(d)
sdk_pkg = packages[sdk_pid][0]
sdk_pkg = packages[first(sdk_pkg["dependencies"], lambda x: True).lower()][0]
msi = []
cabs = []
# download msi files
for pkg in sdk_packages:
payload = first(sdk_pkg["payloads"], lambda p: p["fileName"] == f"Installers\\{pkg}")
if payload is None:
continue
msi.append(DOWNLOADS / pkg)
data = download_progress(payload["url"], payload["sha256"], pkg, pkg)
cabs += list(get_msi_cabs(data))
# download .cab files
for pkg in cabs:
payload = first(sdk_pkg["payloads"], lambda p: p["fileName"] == f"Installers\\{pkg}")
download_progress(payload["url"], payload["sha256"], pkg, pkg)
print("Unpacking msi files...")
# run msi installers
for m in msi:
subprocess.check_call(["msiexec.exe", "/a", m, "/quiet", "/qn", f"TARGETDIR={OUTPUT.resolve()}"])
(OUTPUT / m.name).unlink()
### versions
msvcv = list((OUTPUT / "VC/Tools/MSVC").glob("*"))[0].name
sdkv = list((OUTPUT / "Windows Kits/10/bin").glob("*"))[0].name
# place debug CRT runtime files into MSVC bin filder (not what real Visual Studio installer does... but is reasonable)
redist = OUTPUT / "VC/Redist"
if redist.exists():
src = redist / "MSVC" / msvcv / "debug_nonredist"
for target in targets:
for f in (src / target).glob("**/*.dll"):
dst = OUTPUT / "VC/Tools/MSVC" / msvcv / f"bin/Host{host}" / target
f.replace(dst / f.name)
shutil.rmtree(redist)
# move msdia140.dll file into MSVC folder
msdia140dll = {
"x86": "msdia140.dll",
"x64": "amd64/msdia140.dll",
"arm": "arm/msdia140.dll",
"arm64": "arm64/msdia140.dll",
}
dst = OUTPUT / "VC/Tools/MSVC" / msvcv / f"bin/Host{host}"
src = OUTPUT / "DIA%20SDK/bin" / msdia140dll[host]
for target in targets:
shutil.copyfile(src, dst / target / src.name)
shutil.rmtree(OUTPUT / "DIA%20SDK")
### cleanup
shutil.rmtree(OUTPUT / "Common7", ignore_errors=True)
shutil.rmtree(OUTPUT / "VC/Tools/MSVC" / msvcv / "Auxiliary")
for target in targets:
for f in [f"store", "uwp", "enclave", "onecore"]:
shutil.rmtree(OUTPUT / "VC/Tools/MSVC" / msvcv / "lib" / target / f, ignore_errors=True)
shutil.rmtree(OUTPUT / "VC/Tools/MSVC" / msvcv / f"bin/Host{host}" / target / "onecore", ignore_errors=True)
for f in ["Catalogs", "DesignTime", f"bin/{sdkv}/chpe", f"Lib/{sdkv}/ucrt_enclave"]:
shutil.rmtree(OUTPUT / "Windows Kits/10" / f, ignore_errors=True)
for arch in ["x86", "x64", "arm", "arm64"]:
if arch not in targets:
shutil.rmtree(OUTPUT / "Windows Kits/10/Lib" / sdkv / "ucrt" / arch, ignore_errors=True)
shutil.rmtree(OUTPUT / "Windows Kits/10/Lib" / sdkv / "um" / arch, ignore_errors=True)
if arch != host:
shutil.rmtree(OUTPUT / "VC/Tools/MSVC" / msvcv / f"bin/Host{arch}", ignore_errors=True)
shutil.rmtree(OUTPUT / "Windows Kits/10/bin" / sdkv / arch, ignore_errors=True)
# executable that is collecting & sending telemetry every time cl/link runs
for target in targets:
(OUTPUT / "VC/Tools/MSVC" / msvcv / f"bin/Host{host}/{target}/vctip.exe").unlink(missing_ok=True)
### setup.bat
for target in targets:
SETUP = f"""@echo off
set ROOT=%~dp0
set MSVC_VERSION={msvcv}
set MSVC_HOST=Host{host}
set MSVC_ARCH={target}
set SDK_VERSION={sdkv}
set SDK_ARCH={target}
set MSVC_ROOT=%ROOT%VC\\Tools\\MSVC\\%MSVC_VERSION%
set SDK_INCLUDE=%ROOT%Windows Kits\\10\\Include\\%SDK_VERSION%
set SDK_LIBS=%ROOT%Windows Kits\\10\\Lib\\%SDK_VERSION%
set VCToolsInstallDir=%MSVC_ROOT%\\
set PATH=%MSVC_ROOT%\\bin\\%MSVC_HOST%\\%MSVC_ARCH%;%ROOT%Windows Kits\\10\\bin\\%SDK_VERSION%\\%SDK_ARCH%;%ROOT%Windows Kits\\10\\bin\\%SDK_VERSION%\\%SDK_ARCH%\\ucrt;%PATH%
set INCLUDE=%MSVC_ROOT%\\include;%SDK_INCLUDE%\\ucrt;%SDK_INCLUDE%\\shared;%SDK_INCLUDE%\\um;%SDK_INCLUDE%\\winrt;%SDK_INCLUDE%\\cppwinrt
set LIB=%MSVC_ROOT%\\lib\\%MSVC_ARCH%;%SDK_LIBS%\\ucrt\\%SDK_ARCH%;%SDK_LIBS%\\um\\%SDK_ARCH%
"""
(OUTPUT / f"setup_{target}.bat").write_text(SETUP)
print(f"Total downloaded: {total_download>>20} MB")
print("Done!")
@goyalyashpal
Copy link

goyalyashpal commented May 11, 2024

File "C:\Users\root\Downloads\ep_portable\portable-msvc\portable-msvc.py", line 282, in <module>
    subprocess.check_call(["msiexec.exe", "/a", str(msi), "/quiet", "/qn", f"TARGETDIR={d2}"])

- @valinet at https://gist.github.com/mmozeiko/7f3162ec2988e81e56d5c4e22cde9977?permalink_comment_id=5053578#gistcomment-5053578

hi! it says line 282, and those seem to be the same lines where i faced this issue.
the fixes for those are absorbed already. check if you are using the latest version of this gist.

see the revisions to this gist. it says "revision from last week" github ain't showing any date 🤦

https://gist.github.com/mmozeiko/7f3162ec2988e81e56d5c4e22cde9977/revisions

@mmozeiko
Copy link
Author

Protip - you can switch Embed on top right of page to Clone and then use that URL to do git clone. Then getting updates will very easy - simply doing git pull will get you latest version of code.

@valinet
Copy link

valinet commented May 12, 2024

@goyalyashpal Nah, I am using the latest version and get error 1603, while you got 1619. It is definitely something else, I don't know exactly what. I am running OS build 19044.4291 (LTSC 2021), have checked out d6d965ec296832941a83d512eed057d88552dd36. Whatever, I can patch it on my end just fine...

@mmozeiko
Copy link
Author

That sounds like some kind of per-requisite of msi package is missing. After Python script fails, run the msiexec command manually with extra arguments to produce log file - and check log.txt it produces for more detailed error messages:

msiexec.exe /a c:\path\to\downloads\crtd\vc_RuntimeDebug.msi /quiet /qn TARGETDIR=c:\path\to\temp /L*vx! c:\path\to\log.txt

@mmozeiko
Copy link
Author

msiexec.exe does the same thing (well with many extras which I don't care about).

But they both use same API - MSI Installer api. Here: https://learn.microsoft.com/en-us/windows/win32/msi/installer-function-reference
I am just too lazy to write all the usage code for it, so instead used msiexec directly - it should be always present on windows installation.

@abidanBrito
Copy link

I'm struggling to get this to work with vcpkg, since it looks for a Visual Studio instance. Any idea what could be done?

-- Running vcpkg install
error: in triplet x64-windows: Unable to find a valid Visual Studio instance
Could not locate a complete Visual Studio instance

@ratchetfreak
Copy link

the msiexec.exe calls at lines 282 and 301 should both do a d2.resolve() instead of a straight d2. It failed trying to access a network location for me if I didn't.

@mmozeiko
Copy link
Author

I'm confused about that. d2 is already full path, it's not Path object. It is TemporaryDirectory when formatted to string gives you full path based on relative path to "downloads" folder. How do you get them to be network location?

@ratchetfreak
Copy link

it wasn't a full path for me, doing a print(f" dir: {d2}") in there printed out just dir: downloads\tmpi_xgyz8z without the preceding path. That got interpreted as a network location somehow by msiexec.exe (probably because of how my company setup it's network).

Doing a resolve fixed that.

@mmozeiko
Copy link
Author

Pushed an update. I think it should fix this.

@cairnc
Copy link

cairnc commented Jun 13, 2024

I'm getting an error

Unpacking msi files...
vc_RuntimeDebug.msi ... 100%
cab1.cab ... 100%
VC_diasdk.msi ... 100%
cab1.cab ... 100%
Traceback (most recent call last):
  File "C:\Users\cairn\Desktop\test\portable\portable-msvc.py", line 329, in <module>
    shutil.rmtree(OUTPUT / "Windows Kits/10/Lib" / sdkv / "ucrt" / arch)
  File "C:\Users\cairn\AppData\Local\Programs\Python\Python310\lib\shutil.py", line 749, in rmtree
    return _rmtree_unsafe(path, onerror)
  File "C:\Users\cairn\AppData\Local\Programs\Python\Python310\lib\shutil.py", line 600, in _rmtree_unsafe
    onerror(os.scandir, path, sys.exc_info())
  File "C:\Users\cairn\AppData\Local\Programs\Python\Python310\lib\shutil.py", line 597, in _rmtree_unsafe
    with os.scandir(path) as scandir_it:
FileNotFoundError: [WinError 3] The system cannot find the path specified: 'msvc\\Windows Kits\\10\\Lib\\10.0.26100.0\\ucrt\\arm'

@mmozeiko
Copy link
Author

Pushed a fix. Seems latest Windows SDK v10.0.26100.0 removed 32-bit arm stuff.

@0017031
Copy link

0017031 commented Jun 21, 2024

@mmozeiko
I have a question about the x64/x86 selection of vc_RuntimeDebug.msi.
Is it for HOST or TARGET?

I'm trying for a HOST=x64 TARGET=x86 environment, (MSVC\14.40.33807\bin\Hostx64\x86)
Thus, in my opinion, vc_RuntimeDebug.msi (chip=x86) should be extracted. Right?

@mmozeiko
Copy link
Author

Yeah, you're right. p["chip"] should be compared to TARGET, not HOST. I've pushed updated code.

@amballa
Copy link

amballa commented Jun 28, 2024

Trying to download MSVC 14.39 but getting this error when running the script
FileNotFoundError: [Errno 2] No such file or directory: 'msvc\\VC\\Tools\\MSVC\\14.39.33519\\bin\\Hostx64\\x64\\Microsoft.VisualStudio.Utilities.Internal.dll'

@hellishvictor
Copy link

hellishvictor commented Jul 1, 2024

Hi, I want to share a modification I did days ago on line 23 for those who need to use the script:
Line 23

TARGET = input(f"Target: x64, x86, arm or arm64 ? ")
if not TARGET:
  TARGET = "x64"

That way can be selected different targets; when input field is empty, it set default value (x64).
I don't know python, but that was obvious and worked. However, it would be better if were added numbers to the options (1=x64, 2=x86, etc) or something better. And also, show a list of the available SDK versions and selected them (1. 10.26100, 2. 10.22621, etc).
Cheers.

@goyalyashpal
Copy link

And also, show a list of the available SDK versions and selected them (1. 10.26100, 2. 10.22621, etc).
- @ hellishvictor at https://gist.github.com/mmozeiko/7f3162ec2988e81e56d5c4e22cde9977?permalink_comment_id=5107833#gistcomment-5107833

that was already available as CLI stdin option if i recall correct

@munohikari
Copy link

SDK 26100 seems to be missing a lot of headers, now my projects fail to build complaining it cannot find "winapifamily.h"

@mmozeiko
Copy link
Author

mmozeiko commented Jul 2, 2024

Pushed an update that should fix it. It also allows host/target selection in CLI arguments.

@hellishvictor
Copy link

that was already available as CLI stdin option if i recall correct

Thank you, I'll check it out !

@hellishvictor
Copy link

Pushed an update that should fix it. It also allows host/target selection in CLI arguments.

The previous script worked like a charm, but this fix shows:

Traceback (most recent call last):
  File "C:\Python\Lib\urllib\request.py", line 1344, in do_open
    h.request(req.get_method(), req.selector, req.data, headers,
  File "C:\Python\Lib\http\client.py", line 1336, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "C:\Python\Lib\http\client.py", line 1382, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "C:\Python\Lib\http\client.py", line 1331, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "C:\Python\Lib\http\client.py", line 1091, in _send_output
    self.send(msg)
  File "C:\Python\Lib\http\client.py", line 1035, in send
    self.connect()
  File "C:\Python\Lib\http\client.py", line 1470, in connect
    super().connect()
  File "C:\Python\Lib\http\client.py", line 1001, in connect
    self.sock = self._create_connection(
                ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python\Lib\socket.py", line 853, in create_connection
    raise exceptions[0]
  File "C:\Python\Lib\socket.py", line 838, in create_connection
    sock.connect(sa)
TimeoutError: [WinError 10060] Se produjo un error durante el intento de conexión ya que la parte conectada no respondió adecuadamente tras un periodo de tiempo, o bien se produjo un error en la conexión establecida ya que el host conectado no ha podido responder

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\MSVC\portable-msvc.py", line 97, in <module>
    manifest = json.loads(download(URL))
                          ^^^^^^^^^^^^^
  File "C:\MSVC\portable-msvc.py", line 31, in download
    with urllib.request.urlopen(url, context=ssl_context) as res:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python\Lib\urllib\request.py", line 215, in urlopen
    return opener.open(url, data, timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python\Lib\urllib\request.py", line 515, in open
    response = self._open(req, data)
               ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python\Lib\urllib\request.py", line 532, in _open
    result = self._call_chain(self.handle_open, protocol, protocol +
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python\Lib\urllib\request.py", line 492, in _call_chain
    result = func(*args)
             ^^^^^^^^^^^
  File "C:\Python\Lib\urllib\request.py", line 1392, in https_open
    return self.do_open(http.client.HTTPSConnection, req,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python\Lib\urllib\request.py", line 1347, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [WinError 10060] Se produjo un error durante el intento de conexión ya que la parte conectada no respondió adecuadamente tras un periodo de tiempo, o bien se produjo un error en la conexión establecida ya que el host conectado no ha podido responder>

I'm on Win 7 x64 SP1. And btw, thank you for the implementation of host/target selection in CLI arguments.

@mmozeiko
Copy link
Author

mmozeiko commented Jul 2, 2024

Windows error 10060 is connection timeout error. Either something is too slow on your network, ISP throttling you or timing out connections or DNS requests to some domains. Try opening URL directly in IE, if that does not work, then you need to solve that problem first. Otherwise if that does work then try increasing timeout in urlopen() call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment