# encoding: ascii
# api: powershell
# title: slideshow&nomonitorsleep;
# description: This will display a slideshow and prevent the monitor from sleeping (which may be useful for other purposes). Change the $folder variable to where pictures are located, and change $wait to the time between picture changes. You can move it to another monitor using windows hotkeys (win+shift+arrow). The SetThreadExecutionState p/invoke function with a parameter of (2) causes the display sleep timer to reset, so must be called in a loop to keep the screen active.
# version: 0.1
# type: function
# author: james gentile
# license: CC0
# function: New-PInvoke
# x-poshcode-id: 5979
# x-derived-from-id: 5982
# x-archived: 2015-08-22T03:16:24
# x-published: 2015-08-19T02:42:00
#
#
$folder = "C:\Users\jrg26\Pictures\"
$wait = 10

function New-PInvoke
{
  <#

    .Synopsis
      Generate a powershell function alias to a Win32|C api function
    .Description
      Creates C# code to access a C function, and exposes it via a powershell function
    .Example
      New-PInvoke user32 "void FlashWindow(IntPtr hwnd, bool bInvert)"

Generates a function for FlashWindow which ignores the boolean return value, and allows you to make a window flash to get the user's attention. Once you've created this function, you could use this line to make a 

PowerShell window flash at the end of a long-running script:
        C:\PS>FlashWindow (ps -id $pid).MainWindowHandle $true
    .Parameter Library
        A C Library containing code to invoke
    .Parameter Signature
        The C# signature of the external method
    .Parameter OutputText
        If Set, retuns the source code for the pinvoke method.
        If not, compiles the type. 
    #>
    param(
    [Parameter(Mandatory=$true, 
        HelpMessage="The C Library Containing the Function, i.e. User32")]
    [String]
    $Library,

    [Parameter(Mandatory=$true,
        HelpMessage="The Signature of the Method, i.e.: int GetSystemMetrics(uint Metric)")]
    [String]
    $Signature,

    [Switch]
    $OutputText
    )

    process {
        if ($Library -notlike "*.dll*") {
            $Library+=".dll"
        }
        if ($signature -notlike "*;") {
            $Signature+=";"
        }
        if ($signature -notlike "public static extern*") {
            $signature = "public static extern $signature"
        }
        $name = $($signature -replace "^.*?\s(\w+)\(.*$",'$1')

        $MemberDefinition = "[DllImport(`"$Library`")]`n$Signature"

        if (-not $OutputText) {
            $type = Add-Type -PassThru -Name "PInvoke$(Get-Random)" -MemberDefinition $MemberDefinition
            del -ea 0 Function:Global:$name
            iex "New-Item Function:Global:$name -Value { [$($type.FullName)]::$name.Invoke( `$args ) }"
        } else {
            $MemberDefinition
        }
    }
}

new-pinvoke kernel32 "int SetThreadExecutionState(uint state)"

[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
$form = new-object Windows.Forms.Form
$form.Text = "Image Viewer"
$form.WindowState= "Maximized"
$form.controlbox = $false
$form.formborderstyle = "0"
$form.BackColor = [System.Drawing.Color]::black
$pictureBox = new-object Windows.Forms.PictureBox
$pictureBox.dock = "fill"
$pictureBox.sizemode = 4
$form.controls.add($pictureBox)
$form.Add_Shown( { $form.Activate()} )
$form.Show()
$list=@()
do
{
	if ($list.count -eq 0) 
    	{ 
		[collections.arraylist]$list=@(dir -literalpath $folder * -include *.jpg, *.jpeg, *.bmp, *.png -recurse)
		if ($list.count -eq 0) {"No pictures. Exiting.";exit}
    	}
    	$fileindex = get-random $list.count
	$file = (get-item -ea 0 $list[$fileindex].fullname)
	$list.removeat($fileindex)

        $pictureBox.Image = [System.Drawing.Image]::Fromfile($file.fullname)
	$form.bringtofront()
	$form.refresh()
	"$($file.fullname)"
        Start-Sleep -Seconds $wait    
	SetThreadExecutionState(2) | out-null
}
While ($true)
