Reputation: 189
I am trying to use this method to get the .NET Framework directory (e.g. C:\Windows\Microsoft.NET\v4.0.30319
)
Add-Type -AssemblyName Microsoft.Build.Utilities
$dotNetDir = [Microsoft.Build.Utilities.ToolLocationHelper]::GetPathToDotNetFramework([Microsoft.Build.Utilities.TargetDotNetFrameworkVersion]::VersionLatest)
However, it is returning nothing. No error, just blank.
I know there are other ways to get the .NET directory but I am wondering why this method is not working?
Upvotes: 1
Views: 2360
Reputation: 16596
TL;DR The Microsoft.Build.Utilities
assembly doesn't support framework versions newer than 2.0. Use a newer assembly to get support for newer framework versions.
On 64-bit Windows 10 Professional I get the following output...
PS> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.18362.145
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.18362.145
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
PS> [Microsoft.Build.Utilities.ToolLocationHelper]::GetPathToDotNetFramework([Microsoft.Build.Utilities.TargetDotNetFrameworkVersion]::VersionLatest)
C:\Windows\Microsoft.NET\Framework\v2.0.50727
I also notice that the VersionLatest
enumeration value is an alias for Version20
...
PS> [Microsoft.Build.Utilities.TargetDotNetFrameworkVersion]::VersionLatest
Version20
That is, VersionLatest
evidently doesn't mean "find the latest installed framework version at runtime", it's just a flexible way to specify the latest available version known at compile-time (of that Microsoft.Build.Utilities
assembly), of which there are not many...
PS> $enumType = [Microsoft.Build.Utilities.TargetDotNetFrameworkVersion]
PS> [Enum]::GetNames($enumType) `
| ForEach-Object -Process {
$value = $enumType::$_;
New-Object -TypeName 'PSCustomObject' -Property (
[Ordered] @{
Name = $_;
ValueText = $value;
ValueInt32 = [Int32] $value
}
)
}
Name ValueText ValueInt32
---- --------- ----------
Version11 Version11 0
Version20 Version20 1
VersionLatest Version20 1
Regarding the results you see on different operating systems, Windows 7 has .NET 2.0 installed by default and, if I recall, Windows 10 has .NET 4.0 but not 2.0 installed by default, so if you didn't change anything that would explain why you get outdated results on Windows 7 and no results on Windows 10. I do have .NET 2.0 as an installed feature on Windows 10, which is why the method is able to find that framework directory.
To fix this, you need to use a newer Microsoft.Build.Utilities*
assembly, which uses a new name for each version. On my system I have Microsoft.Build.Utilities
and Microsoft.Build.Utilities.v3.5
in the GAC, but the latter only supports up to .NET 3.5. Instead, I installed Microsoft.Build.Utilities.Core
from NuGet...
PS> Install-Package -Name 'Microsoft.Build.Utilities.Core' -ProviderName 'NuGet'
After passing Microsoft.Build.Utilities.Core.dll
and its dependencies to Add-Type
, I get a much longer list of Microsoft.Build.Utilities.TargetDotNetFrameworkVersion
values using the snippet above...
Name ValueText ValueInt32
---- --------- ----------
Version11 Version11 0
Version20 Version20 1
Version30 Version30 2
Version35 Version35 3
Version40 Version40 4
Version45 Version45 5
Version451 Version451 6
Version46 Version46 7
Version461 Version461 8
Version452 Version452 9
Version462 VersionLatest 10
VersionLatest VersionLatest 10
Version47 Version47 11
Version471 Version471 12
Version472 Version472 13
Latest Latest 9999
Now your original code finally returns the directory for .NET 4.0...
PS> [Microsoft.Build.Utilities.ToolLocationHelper]::GetPathToDotNetFramework([Microsoft.Build.Utilities.TargetDotNetFrameworkVersion]::VersionLatest)
C:\Windows\Microsoft.NET\Framework64\v4.0.30319
I notice there is a new Latest
enumeration value as well which looks like it really does mean "the version of the latest installed framework", though it (currently) returns the same path as passing VersionLatest
.
Upvotes: 2