Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

windows_sdk.zig: Reinstate COM ISetupEnumInstances logic #16594

Merged
merged 2 commits into from
Jul 29, 2023

Conversation

squeek502
Copy link
Collaborator

@squeek502 squeek502 commented Jul 28, 2023

The C++ version of this code used this logic, and it turns out it is able to find some setups that the current registry/Vs7 methods cannot.

For example, if only the "Build Tools for Visual Studio" are installed but not Visual Studio itself, then only the ISetupEnumInstances method seems to find it.

Follow up to #15657, fixes a regression caused by moving from the C++ version to the Zig version


Needs some testing for sure. I've only tested it on one setup with only the build tools installed so far.

Here's a build of libc_only.exe (detailed here: #15657 (comment)) if anyone wants to test their setup:

libc_only-20230728.zip

Otherwise, to test this, build this branch and run zig libc


Before, with only the build tools installed:

error: unable to detect native libc: LibCStdLibHeaderNotFound

After:

# The directory that contains `stdlib.h`.
# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`
include_dir=C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\ucrt

# The system-specific include directory. May be the same as `include_dir`.
# On Windows it's the directory that includes `vcruntime.h`.
# On POSIX it's the directory that includes `sys/errno.h`.
sys_include_dir=C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.36.32532\include

# The directory that contains `crt1.o` or `crt2.o`.
# On POSIX, can be found with `cc -print-file-name=crt1.o`.
# Not needed when targeting MacOS.
crt_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\ucrt\x64

# The directory that contains `vcruntime.lib`.
# Only needed when targeting MSVC on Windows.
msvc_lib_dir=C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.36.32532\Lib\x64

# The directory that contains `kernel32.lib`.
# Only needed when targeting MSVC on Windows.
kernel32_lib_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\um\x64

# The directory that contains `crtbeginS.o` and `crtendS.o`
# Only needed when targeting Haiku.
gcc_dir=

cc @BratishkaErik

src/windows_sdk.zig Outdated Show resolved Hide resolved
@BratishkaErik
Copy link
Contributor

IIUC, seems like this is the best approach to detect? I'll test it tomorrow in the morning too. Thank you so much!
I have started another branch in my fork, which changes some logic regarding using these founded libraries, but I'll delay it until this lands.
Again, thanks :) I don't think there is any need in my help there (I'm clearly much less experienced in all this stuff rn)

The C++ version of this code used this logic, and it turns out it is able to find some setups that the current registry/Vs7 methods cannot.

For example, if only the "Build Tools for Visual Studio" are installed but not Visual Studio itself, then only the ISetupEnumInstances method seems to find it.

Follow up to ziglang#15657, fixes a regression caused by moving from the C++ version to the Zig version
@squeek502 squeek502 marked this pull request as ready for review July 29, 2023 02:33
@sgwong
Copy link

sgwong commented Jul 29, 2023

This patch does fix for 1 of my win11 pc which only have VS2019 build tool install.

For my other window 11 pc with both VS2019 build tools and VS2022 community, it detects the VS2019 build tools with this fix(the zig master detected the VS2022). Zig previously with cpp code is also detect the VS2019 build tools which seems fine for me.

For windows 11 pc with only VS2022 community, it does able to detect the lib (same output for both zig master & the libc_only)

zig master 0.11.0-dev.4296+7e25fb4a4 PC with VS2019 build tools and VS2022
# The directory that contains `stdlib.h`.
# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`
include_dir=C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\ucrt

# The system-specific include directory. May be the same as `include_dir`.
# On Windows it's the directory that includes `vcruntime.h`.
# On POSIX it's the directory that includes `sys/errno.h`.
sys_include_dir=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include

# The directory that contains `crt1.o` or `crt2.o`.
# On POSIX, can be found with `cc -print-file-name=crt1.o`.
# Not needed when targeting MacOS.
crt_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\ucrt\x64

# The directory that contains `vcruntime.lib`.
# Only needed when targeting MSVC on Windows.
msvc_lib_dir=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\Lib\x64

# The directory that contains `kernel32.lib`.
# Only needed when targeting MSVC on Windows.
kernel32_lib_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\um\x64

# The directory that contains `crtbeginS.o` and `crtendS.o`
# Only needed when targeting Haiku.
gcc_dir=
libc_only PC with VS2019 build tools and VS2022
# The directory that contains `stdlib.h`.
# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`
include_dir=C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\ucrt

# The system-specific include directory. May be the same as `include_dir`.
# On Windows it's the directory that includes `vcruntime.h`.
# On POSIX it's the directory that includes `sys/errno.h`.
sys_include_dir=C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\include

# The directory that contains `crt1.o` or `crt2.o`.
# On POSIX, can be found with `cc -print-file-name=crt1.o`.
# Not needed when targeting MacOS.
crt_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\ucrt\x64

# The directory that contains `vcruntime.lib`.
# Only needed when targeting MSVC on Windows.
msvc_lib_dir=C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\Lib\x64

# The directory that contains `kernel32.lib`.
# Only needed when targeting MSVC on Windows.
kernel32_lib_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\um\x64

# The directory that contains `crtbeginS.o` and `crtendS.o`
# Only needed when targeting Haiku.
gcc_dir=
zig master & libc_only PC with VS2022 community only
# The directory that contains `stdlib.h`.
# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`
include_dir=C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\ucrt

# The system-specific include directory. May be the same as `include_dir`.
# On Windows it's the directory that includes `vcruntime.h`.
# On POSIX it's the directory that includes `sys/errno.h`.
sys_include_dir=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include

# The directory that contains `crt1.o` or `crt2.o`.
# On POSIX, can be found with `cc -print-file-name=crt1.o`.
# Not needed when targeting MacOS.
crt_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\ucrt\x64

# The directory that contains `vcruntime.lib`.
# Only needed when targeting MSVC on Windows.
msvc_lib_dir=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\Lib\x64

# The directory that contains `kernel32.lib`.
# Only needed when targeting MSVC on Windows.
kernel32_lib_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\um\x64

# The directory that contains `crtbeginS.o` and `crtendS.o`
# Only needed when targeting Haiku.
gcc_dir=

@squeek502
Copy link
Collaborator Author

squeek502 commented Jul 29, 2023

@sgwong, thanks for testing. Right now this (and the old C++ version) only checks the first installation path returned from IEnumSetupInstances if vcruntime.lib was found in its lib dir. Instead, I think it should iterate them all and pick the latest version (which is what the findViaRegistry is doing).

Will update findViaCOM to do that.

Before, iteration would stop whenever an installation with vcruntime.lib was found, but that may not be the most recent installed version. Instead, we now iterate all installed instances and choose the one with the newest version.
@squeek502
Copy link
Collaborator Author

squeek502 commented Jul 29, 2023

@sgwong here's an updated libc_only.exe with a debug print included that will print each installed instance found:

libc_only-20230728.zip

Let me know what your results are with that.

@sgwong
Copy link

sgwong commented Jul 29, 2023

This is the latest output on pc with multiple build tools and VS installation. It does find the latest VS2022 now.

[debug] Found version: 16.10.31424.327 (4503644636447047L)

[debug] Found version: 15.9.28307.1525 (4222165160494581L)

[debug] Found version: 16.11.31729.503 (4503648951402999L)

[debug] Found version: 17.6.33829.357 (4785102590902629L)

# The directory that contains `stdlib.h`.
# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`
include_dir=C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\ucrt

# The system-specific include directory. May be the same as `include_dir`.
# On Windows it's the directory that includes `vcruntime.h`.
# On POSIX it's the directory that includes `sys/errno.h`.
sys_include_dir=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include

# The directory that contains `crt1.o` or `crt2.o`.
# On POSIX, can be found with `cc -print-file-name=crt1.o`.
# Not needed when targeting MacOS.
crt_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\ucrt\x64

# The directory that contains `vcruntime.lib`.
# Only needed when targeting MSVC on Windows.
msvc_lib_dir=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\Lib\x64

# The directory that contains `kernel32.lib`.
# Only needed when targeting MSVC on Windows.
kernel32_lib_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\um\x64

# The directory that contains `crtbeginS.o` and `crtendS.o`
# Only needed when targeting Haiku.
gcc_dir=

@yuyoyuppe
Copy link

yuyoyuppe commented Jul 29, 2023

There might be another way to detect this without using COM API.
local function get_latest_vs_install_path()
    local instances_dir = "C:\\ProgramData\\Microsoft\\VisualStudio\\Packages\\_Instances\\"

    local instance_ids = {}
    for instance in io.popen('dir "' .. instances_dir .. '" /b /ad'):lines() do
        table.insert(instance_ids, instance)
    end

    local newest_version = "0.0.0"
    local newest_path = nil

    for _, instance_id in ipairs(instance_ids) do
        local state_path = instances_dir .. instance_id .. "\\state.json"

        local file = io.open(state_path, "r")
        if file then
            local content = file:read("*all")
            file:close()

            local version = content:match('"buildVersion"%s-:%s-"(.-)%+')
            local path = content:match('"installationPath"%s-:%s-"(.-)"')

            if version and path and version > newest_version then
                newest_version = version
                newest_path = path
            end
        end
    end

@BratishkaErik
Copy link
Contributor

Visual Studio Community 2022 with MSVC 143 (C++ build tools, C++ libraries and Visual C++ stuff), MSBuild support for Clang/LLVM, UCRT package, MSVC 140 (build tools only), two windows 10 sdks:
master:

# The directory that contains `stdlib.h`.
# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`
include_dir=C:\Program Files (x86)\Windows Kits\10\Include\10.0.20348.0\ucrt

# The system-specific include directory. May be the same as `include_dir`.
# On Windows it's the directory that includes `vcruntime.h`.
# On POSIX it's the directory that includes `sys/errno.h`.
sys_include_dir=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include

# The directory that contains `crt1.o` or `crt2.o`.
# On POSIX, can be found with `cc -print-file-name=crt1.o`.
# Not needed when targeting MacOS.
crt_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.20348.0\ucrt\x64

# The directory that contains `vcruntime.lib`.
# Only needed when targeting MSVC on Windows.
msvc_lib_dir=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\Lib\x64

# The directory that contains `kernel32.lib`.
# Only needed when targeting MSVC on Windows.
kernel32_lib_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.20348.0\um\x64

# The directory that contains `crtbeginS.o` and `crtendS.o`
# Only needed when targeting Haiku.
gcc_dir=

This branch:

[debug] Found version: 17.5.33627.172 (4785098282696876L)

# The directory that contains `stdlib.h`.
# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`
include_dir=C:\Program Files (x86)\Windows Kits\10\Include\10.0.20348.0\ucrt

# The system-specific include directory. May be the same as `include_dir`.
# On Windows it's the directory that includes `vcruntime.h`.
# On POSIX it's the directory that includes `sys/errno.h`.
sys_include_dir=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include

# The directory that contains `crt1.o` or `crt2.o`.
# On POSIX, can be found with `cc -print-file-name=crt1.o`.
# Not needed when targeting MacOS.
crt_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.20348.0\ucrt\x64

# The directory that contains `vcruntime.lib`.
# Only needed when targeting MSVC on Windows.
msvc_lib_dir=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\Lib\x64

# The directory that contains `kernel32.lib`.
# Only needed when targeting MSVC on Windows.
kernel32_lib_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.20348.0\um\x64

# The directory that contains `crtbeginS.o` and `crtendS.o`
# Only needed when targeting Haiku.
gcc_dir=

(same result)

Everything as in above, but without IDE:
master:

This branch:

(regression fixed!)

@BratishkaErik
Copy link
Contributor

IDK what happened, but after rebooting libc_only.exe doesn't work:

[debug] Found version: 17.6.33829.357 (4785102590902629L)

error: unable to detect native libc: LibCStdLibHeaderNotFound

Previously, it printed like on master with IDE. Maybe after rebooting IDE finished uninstalling or smth similar, IDK.

@BratishkaErik
Copy link
Contributor

IDK what happened, but after rebooting libc_only.exe doesn't work:

[debug] Found version: 17.6.33829.357 (4785102590902629L)

error: unable to detect native libc: LibCStdLibHeaderNotFound

Previously, it printed like on master with IDE. Maybe after rebooting IDE finished uninstalling or smth similar, IDK.

After another rebooting, it suddenly started to work again (but with slightly different path for MSVC):

[debug] Found version: 17.5.33627.172 (4785098282696876L)

# The directory that contains `stdlib.h`.
# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`
include_dir=C:\Program Files (x86)\Windows Kits\10\Include\10.0.20348.0\ucrt

# The system-specific include directory. May be the same as `include_dir`.
# On Windows it's the directory that includes `vcruntime.h`.
# On POSIX it's the directory that includes `sys/errno.h`.
sys_include_dir=C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.35.32215\include

# The directory that contains `crt1.o` or `crt2.o`.
# On POSIX, can be found with `cc -print-file-name=crt1.o`.
# Not needed when targeting MacOS.
crt_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.20348.0\ucrt\x64

# The directory that contains `vcruntime.lib`.
# Only needed when targeting MSVC on Windows.
msvc_lib_dir=C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.35.32215\Lib\x64

# The directory that contains `kernel32.lib`.
# Only needed when targeting MSVC on Windows.
kernel32_lib_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.20348.0\um\x64

# The directory that contains `crtbeginS.o` and `crtendS.o`
# Only needed when targeting Haiku.
gcc_dir=

@andrewrk andrewrk merged commit b8dda2d into ziglang:master Jul 29, 2023
@squeek502
Copy link
Collaborator Author

squeek502 commented Jul 29, 2023

@yuyoyuppe using ProcessMonitor, it looks like that's what the COM stuff is doing internally:

com-process-monitor

Good to know, but might as well use the COM stuff since the code is already written now and is the recommended-by-Microsoft way of doing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants