Last active
January 8, 2017 18:05
-
-
Save mkropat/d8b744c994eaa59493648f8795d9dde8 to your computer and use it in GitHub Desktop.
Calculate the value for just about any constant in the Windows SDK
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory = $true)] | |
[string] $Name | |
) | |
$ErrorActionPreference = 'Continue' | |
function Main { | |
$buildDir = New-TemporaryDirectory | |
Push-Location $buildDir | |
try { | |
$sourcePath = Join-Path $buildDir 'getconstant.cpp' | |
Get-ConstantCppSource $Name | Out-File $sourcePath -Encoding ascii | |
Set-VisualStudioEnvironmentVariables | |
& (Get-ClPath) /EHsc $sourcePath 2>&1 | Out-Null | |
if ($LASTEXITCODE -ne 0) { | |
Write-Error "Unable to locate constant '$Name'" | |
exit 1 | |
} | |
& $buildDir\getconstant.exe | |
} | |
finally { | |
Pop-Location | |
Remove-Item -Recurse $buildDir | |
} | |
} | |
function Get-VisualStudioToolsPath { | |
$toolsDir = 99..1 | | |
foreach { Get-EnvironmentVariable "VS${_}0COMNTOOLS" } | | |
where { $_ } | | |
select -First 1 | |
if (-not $toolsDir) { | |
throw "Unable to locate Visual Studio install directory. Have you installed it?" | |
} | |
Write-Output $toolsDir | |
} | |
function Get-ClPath { | |
$toolsDir = Get-VisualStudioToolsPath | |
$binDir = Resolve-Path "$toolsDir\..\..\VC\bin" | |
Join-Path $binDir 'cl.exe' | |
} | |
function Get-IncludeDir { | |
if (-not (Test-Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots')) { | |
throw "Unable to locate Windows 10 SDK. Have you installed it?" | |
} | |
$sdkDir = Get-ItemPropertyValue "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots" -Name KitsRoot10 | |
$includeDir = Join-Path $sdkDir 'Include' | |
$newestVersion = Get-ChildItem $includeDir | | |
sort Name -Descending | | |
select -First 1 -ExpandProperty Name | |
Join-Path $includeDir $newestVersion | |
} | |
function Get-IncludeFiles { | |
param( | |
[string] $Name | |
) | |
Get-ChildItem (Get-IncludeDir) -Recurse -Include '*.h' | | |
where { | |
Select-String -Path $_ -SimpleMatch -CaseSensitive -Pattern "#define $Name" -List | |
} | |
} | |
function Get-ConstantCppSource() { | |
param( | |
[string] $Name | |
) | |
$includes = Get-IncludeFiles $Name | foreach { "#include <$($_.Name)>" } | |
@" | |
#include <iostream> | |
#include <Windows.h> | |
$($includes -join "`n") | |
using namespace std; | |
void repr(void *value) { cout << (long)value << endl; } | |
void repr(int value) { cout << value << endl; } | |
void repr(unsigned int value) { cout << value << endl; } | |
void repr(long value) { cout << value << endl; } | |
void repr(unsigned long value) { cout << value << endl; } | |
void repr(char* value) { cout << '\"' << value << '\"' << endl; } | |
int main() | |
{ | |
repr($Name); | |
return 0; | |
} | |
"@ | |
} | |
function Set-VisualStudioEnvironmentVariables { | |
if ($env:DevEnvDir) { | |
return | |
} | |
$toolsDir = Get-VisualStudioToolsPath | |
$batPath = [IO.Path]::GetTempFileName() -replace 'tmp$','bat' | |
@" | |
@echo off | |
call "$toolsDir\VsDevCmd.bat" | |
set | |
"@ | Out-File -Encoding ascii $batPath | |
& $env:ComSpec /c $batPath | foreach { | |
$parts = $_.Split('=', 2) | |
[Environment]::SetEnvironmentVariable($parts[0], $parts[1], [EnvironmentVariableTarget]::Process) | |
} | |
Remove-Item $batPath | |
} | |
function Get-EnvironmentVariable { | |
param( | |
[string] $Name | |
) | |
[Environment]::GetEnvironmentVariable($Name, [EnvironmentVariableTarget]::Process) | |
} | |
function New-TemporaryDirectory { | |
$parent = [System.IO.Path]::GetTempPath() | |
[string] $name = [System.Guid]::NewGuid() | |
New-Item -ItemType Directory -Path (Join-Path $parent $name) | |
} | |
Main | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory = $true)] | |
[string] $Name | |
) | |
$ErrorActionPreference = 'Continue' | |
function Main { | |
$buildDir = New-TemporaryDirectory | |
Push-Location $buildDir | |
try { | |
$sourcePath = Join-Path $buildDir 'getconstant.cpp' | |
Get-ConstantCppSource $Name | Out-File $sourcePath -Encoding ascii | |
Set-VisualStudioEnvironmentVariables | |
& (Get-ClPath) /EHsc $sourcePath 2>&1 | Out-Null | |
if ($LASTEXITCODE -ne 0) { | |
Write-Error "Unable to locate constant '$Name'" | |
exit 1 | |
} | |
& $buildDir\getconstant.exe | |
} | |
finally { | |
Pop-Location | |
Remove-Item -Recurse $buildDir | |
} | |
} | |
function Get-VisualStudioToolsPath { | |
$toolsDir = 99..1 | | |
foreach { Get-EnvironmentVariable "VS${_}0COMNTOOLS" } | | |
where { $_ } | | |
select -First 1 | |
if (-not $toolsDir) { | |
throw "Unable to locate Visual Studio install directory. Have you installed it?" | |
} | |
Write-Output $toolsDir | |
} | |
function Get-ClPath { | |
$toolsDir = Get-VisualStudioToolsPath | |
$binDir = Resolve-Path "$toolsDir\..\..\VC\bin" | |
Join-Path $binDir 'cl.exe' | |
} | |
function Get-IncludeDir { | |
if (-not (Test-Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots')) { | |
throw "Unable to locate Windows 10 SDK. Have you installed it?" | |
} | |
$sdkDir = Get-ItemPropertyValue "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots" -Name KitsRoot10 | |
$includeDir = Join-Path $sdkDir 'Include' | |
$newestVersion = Get-ChildItem $includeDir | | |
sort Name -Descending | | |
select -First 1 -ExpandProperty Name | |
Join-Path $includeDir $newestVersion | |
} | |
function Get-IncludeFiles { | |
param( | |
[string] $Name | |
) | |
Get-ChildItem (Get-IncludeDir) -Recurse -Include '*.h' | | |
where { | |
Select-String -Path $_ -SimpleMatch -CaseSensitive -Pattern "#define $Name" -List | |
} | |
} | |
function Get-ConstantCppSource() { | |
param( | |
[string] $Name | |
) | |
$includes = Get-IncludeFiles $Name | foreach { "#include <$($_.Name)>" } | |
@" | |
#include <iostream> | |
#include <Windows.h> | |
$($includes -join "`n") | |
using namespace std; | |
void repr(void *value) { cout << (long)value << endl; } | |
void repr(int value) { cout << value << endl; } | |
void repr(unsigned int value) { cout << value << endl; } | |
void repr(long value) { cout << value << endl; } | |
void repr(unsigned long value) { cout << value << endl; } | |
void repr(char* value) { cout << '\"' << value << '\"' << endl; } | |
int main() | |
{ | |
repr($Name); | |
return 0; | |
} | |
"@ | |
} | |
function Set-VisualStudioEnvironmentVariables { | |
if ($env:DevEnvDir) { | |
return | |
} | |
$toolsDir = Get-VisualStudioToolsPath | |
$batPath = [IO.Path]::GetTempFileName() -replace 'tmp$','bat' | |
@" | |
@echo off | |
call "$toolsDir\VsDevCmd.bat" | |
set | |
"@ | Out-File -Encoding ascii $batPath | |
& $env:ComSpec /c $batPath | foreach { | |
$parts = $_.Split('=', 2) | |
[Environment]::SetEnvironmentVariable($parts[0], $parts[1], [EnvironmentVariableTarget]::Process) | |
} | |
Remove-Item $batPath | |
} | |
function Get-EnvironmentVariable { | |
param( | |
[string] $Name | |
) | |
[Environment]::GetEnvironmentVariable($Name, [EnvironmentVariableTarget]::Process) | |
} | |
function New-TemporaryDirectory { | |
$parent = [System.IO.Path]::GetTempPath() | |
[string] $name = [System.Guid]::NewGuid() | |
New-Item -ItemType Directory -Path (Join-Path $parent $name) | |
} | |
Main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment