@@ -250,6 +250,15 @@ private:
250
250
if (VSInstallDir is null )
251
251
VSInstallDir = GetRegistryString(r " Microsoft\VisualStudio\SxS\VS7" , " 15.0" w); // VS2017
252
252
253
+ if (VSInstallDir is null )
254
+ {
255
+ wchar [260 ] buffer = void ;
256
+ // VS Build Tools 2017 (default installation path)
257
+ const numWritten = ExpandEnvironmentStringsW(r " %ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools" w.ptr, buffer.ptr, buffer.length);
258
+ if (numWritten <= buffer.length && exists(buffer.ptr))
259
+ VSInstallDir = toNarrow(buffer.ptr);
260
+ }
261
+
253
262
if (VSInstallDir is null )
254
263
foreach (const (char )* ver; supportedPre2017Versions)
255
264
{
@@ -760,15 +769,46 @@ const(char)* detectVSInstallDirViaCOM()
760
769
return null ;
761
770
scope (exit) instances.Release();
762
771
772
+ static struct WrappedBString
773
+ {
774
+ BSTR ptr;
775
+ this (this ) @disable ;
776
+ ~this () { SysFreeString(ptr); }
777
+ bool opCast (T : bool )() { return ptr ! is null ; }
778
+ size_t length () { return SysStringLen(ptr); }
779
+ void moveTo (ref WrappedBString other)
780
+ {
781
+ SysFreeString(other.ptr);
782
+ other.ptr = ptr;
783
+ ptr = null ;
784
+ }
785
+ }
786
+
787
+ WrappedBString versionString, installDir;
788
+
763
789
while (instances.Next(1 , &instance, &fetched) == S_OK && fetched)
764
790
{
765
- BSTR bstrInstallDir;
766
- if (instance.GetInstallationPath(&bstrInstallDir) != S_OK )
791
+ WrappedBString thisVersionString, thisInstallDir;
792
+ if (instance.GetInstallationVersion(&thisVersionString.ptr) != S_OK ||
793
+ instance.GetInstallationPath(&thisInstallDir.ptr) != S_OK )
767
794
continue ;
768
- scope (exit) SysFreeString (bstrInstallDir);
769
795
770
- if (SysStringLen(bstrInstallDir))
771
- return toNarrow (bstrInstallDir);
796
+ // FIXME: proper version strings comparison
797
+ if (versionString && wcscmp(thisVersionString.ptr, versionString.ptr) <= 0 )
798
+ continue ; // not a newer version, skip
799
+
800
+ const installDirLength = thisInstallDir.length;
801
+ const vcInstallDirLength = installDirLength + 4 ;
802
+ auto vcInstallDir = (cast (wchar * ) mem.xmalloc_noscan(vcInstallDirLength * wchar .sizeof))[0 .. vcInstallDirLength];
803
+ scope (exit) mem.xfree(vcInstallDir.ptr);
804
+ vcInstallDir[0 .. installDirLength] = thisInstallDir.ptr[0 .. installDirLength];
805
+ vcInstallDir[installDirLength .. $] = " \\ VC\0 " w;
806
+ if (! exists(vcInstallDir.ptr))
807
+ continue ; // Visual C++ not included, skip
808
+
809
+ thisVersionString.moveTo(versionString);
810
+ thisInstallDir.moveTo(installDir);
772
811
}
773
- return null ;
812
+
813
+ return installDir ? toNarrow(installDir.ptr) : null ;
774
814
}
0 commit comments