Skip to content

Instantly share code, notes, and snippets.

@adamdriscoll
Created March 21, 2016 20:52
Show Gist options
  • Save adamdriscoll/13b6fdd75db7c0797d5a to your computer and use it in GitHub Desktop.
Save adamdriscoll/13b6fdd75db7c0797d5a to your computer and use it in GitHub Desktop.
Beeping Computer
## Invoke a Win32 P/Invoke call.
function Invoke-Win32([string] $dllName, [Type] $returnType,
[string] $methodName, [Type[]] $parameterTypes, [Object[]] $parameters)
{
## Begin to build the dynamic assembly
$domain = [AppDomain]::CurrentDomain
$name = New-Object Reflection.AssemblyName �PInvokeAssembly�
$assembly = $domain.DefineDynamicAssembly($name, �Run�)
$module = $assembly.DefineDynamicModule(�PInvokeModule�)
$type = $module.DefineType(�PInvokeType�, �Public,BeforeFieldInit�)
## Go through all of the parameters passed to us. As we do this,
## we clone the user�s inputs into another array that we will use for
## the P/Invoke call.
$inputParameters = @()
$refParameters = @()
for($counter = 1; $counter -le $parameterTypes.Length; $counter++)
{
## If an item is a PSReference, then the user
## wants an [out] parameter.
if($parameterTypes[$counter - 1] -eq [Ref])
{
## Remember which parameters are used for [Out] parameters
$refParameters += $counter
##On the cloned array, we replace the PSReference type with the
##.Net reference type that represents the value of the PSReference,
##and the value with the value held by the PSReference.
$parameterTypes[$counter - 1] =
$parameters[$counter - 1].Value.GetType().MakeByRefType()
$inputParameters += $parameters[$counter - 1].Value
}
else
{
## Otherwise, just add their actual parameter to the
## input array.
$inputParameters += $parameters[$counter - 1]
}
}
## Define the actual P/Invoke method, adding the [Out]
## attribute for any parameters that were originally [Ref]
## parameters.
$method = $type.DefineMethod($methodName, 'Public,HideBySig,Static,PinvokeImpl',
$returnType, $parameterTypes)
foreach($refParameter in $refParameters)
{
$method.DefineParameter($refParameter, "Out", $null)
}
## Apply the P/Invoke constructor
$ctor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([string])
$attr = New-Object Reflection.Emit.CustomAttributeBuilder $ctor, $dllName
$method.SetCustomAttribute($attr)
## Create the temporary type, and invoke the method.
$realType = $type.CreateType()
$realType.InvokeMember($methodName, �Public,Static,InvokeMethod�, $null, $null,
$inputParameters)
## Finally, go through all of the reference parameters, and update the
## values of the PSReference objects that the user passed in.
foreach($refParameter in $refParameters)
{
$parameters[$refParameter - 1].Value = $inputParameters[$refParameter - 1]
}
}
function Invoke-Beep($frequency, $duration)
{
Invoke-Win32 -dllName Kernel32.dll -methodName "Beep" -parameterTypes @([int],[int]) -parameters $frequency, $duration
}
function Invoke-Beethoven()
{
Invoke-Beep 659 120 # Treble E
Invoke-Beep 0 120
Invoke-Beep 622 120 # Treble D#
Invoke-Beep 0 120
Invoke-Beep 659 120 # Treble E
Invoke-Beep 0 120
Invoke-Beep 622 120 # Treble D#
Invoke-Beep 0 120
Invoke-Beep 659 120 # Treble E
Invoke-Beep 0 120
Invoke-Beep 494 120 # Treble B
Invoke-Beep 0 120
Invoke-Beep 587 120 # Treble D
Invoke-Beep 0 120
Invoke-Beep 523 120 # Treble C
Invoke-Beep 0 120
Invoke-Beep 440 120 # Treble A
Invoke-Beep 0 140
Invoke-Beep 262 120 # Middle C
Invoke-Beep 0 120
Invoke-Beep 330 120 # Treble E
Invoke-Beep 0 120
Invoke-Beep 440 120 # Treble A
Invoke-Beep 0 120
Invoke-Beep 494 120 # Treble B
Invoke-Beep 0 140
Invoke-Beep 330 120 # Treble E
Invoke-Beep 0 120
Invoke-Beep 415 120 # Treble G#
Invoke-Beep 0 120
Invoke-Beep 494 120 # Treble B
Invoke-Beep 0 120
Invoke-Beep 523 120 # Treble C
Invoke-Beep 0 140
Invoke-Beep 330 120 # Treble E
Invoke-Beep 0 120
Invoke-Beep 659 120 # Treble E
Invoke-Beep 0 120
Invoke-Beep 622 120 # Treble D#
Invoke-Beep 0 120
Invoke-Beep 659 120 # Treble E
Invoke-Beep 0 120
Invoke-Beep 622 120 # Treble D#
Invoke-Beep 0 120
Invoke-Beep 659 120 # Treble E
Invoke-Beep 0 120
Invoke-Beep 494 120 # Treble B
Invoke-Beep 0 120
Invoke-Beep 587 120 # Treble D
Invoke-Beep 0 120
Invoke-Beep 523 120 # Treble C
Invoke-Beep 0 120
Invoke-Beep 440 120 # Treble A
Invoke-Beep 0 140
Invoke-Beep 262 120 # Middle C
Invoke-Beep 0 120
Invoke-Beep 330 120 # Treble E
Invoke-Beep 0 120
Invoke-Beep 440 120 # Treble A
Invoke-Beep 0 120
Invoke-Beep 494 120 # Treble B
Invoke-Beep 0 140
Invoke-Beep 330 120 # Treble E
Invoke-Beep 0 120
Invoke-Beep 523 120 # Treble C
Invoke-Beep 0 120
Invoke-Beep 494 120 # Treble B
Invoke-Beep 0 140
Invoke-Beep 440 120 # Treble A
}
Invoke-Beethoven
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment