Skip to content

Commit

Permalink
PowerRemoteDesktop v3.0 (#22)
Browse files Browse the repository at this point in the history
* Prevent computer to sleep in server side.
* Motion Update now supported in its very first version to increase desktop streaming speed.
* Mouse move works as expected in certain circumstances.
* Keyboard simulation improved.
* Various Optimization and fixes.
  • Loading branch information
DarkCoderSc authored Feb 9, 2022
1 parent 966fb86 commit a0abeff
Show file tree
Hide file tree
Showing 8 changed files with 798 additions and 343 deletions.
Binary file added Assets/PowerShell_Core_6.0_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified PowerRemoteDesktop_Server/PowerRemoteDesktop_Server.psd1
Binary file not shown.
849 changes: 580 additions & 269 deletions PowerRemoteDesktop_Server/PowerRemoteDesktop_Server.psm1

Large diffs are not rendered by default.

Binary file modified PowerRemoteDesktop_Viewer/PowerRemoteDesktop_Viewer.psd1
Binary file not shown.
183 changes: 139 additions & 44 deletions PowerRemoteDesktop_Viewer/PowerRemoteDesktop_Viewer.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,6 @@
Version 2.0, January 2004
http://www.apache.org/licenses/
.Why
- Prove PowerShell is as "PowerFul" as compiled language.
- Improve my PowerShell skills.
- Because Remote Desktop Powershell Scripts doesn't exists so far.
.Important
This PowerShell Application is not yet marked as Stable / Final. It is not recommended to use
it in a production environment at this time.
Wait for final 1.0 version.
.Disclaimer
We are doing our best to prepare the content of this app. However, PHROZEN SASU and / or
Jean-Pierre LESUEUR cannot warranty the expressions and suggestions of the contents,
Expand All @@ -49,9 +39,19 @@
-------------------------------------------------------------------------------#>

Add-Type -Assembly System.Windows.Forms
Add-Type -MemberDefinition '[DllImport("User32.dll")] public static extern bool SetProcessDPIAware();' -Name User32 -Namespace W;

$global:PowerRemoteDesktopVersion = "2.0.0"
Add-Type @"
using System;
using System.Runtime.InteropServices;
public static class User32
{
[DllImport("User32.dll")]
public static extern bool SetProcessDPIAware();
}
"@

$global:PowerRemoteDesktopVersion = "3.0.0"

$global:HostSyncHash = [HashTable]::Synchronized(@{
host = $host
Expand Down Expand Up @@ -87,6 +87,25 @@ enum WorkerKind {
Events = 2
}

enum BlockSize {
Size32 = 32
Size64 = 64
Size96 = 96
Size128 = 128
Size256 = 256
Size512 = 512
}

enum PacketSize {
Size1024 = 1024
Size2048 = 2048
Size4096 = 4096
Size8192 = 8192
Size9216 = 9216
Size12288 = 12288
Size16384 = 16384
}

function Write-Banner
{
<#
Expand Down Expand Up @@ -718,16 +737,17 @@ class ViewerSession
[bool] $UseTLSv1_3 = $false
[int] $ImageCompressionQuality = 100
[int] $ResizeRatio = 0
[PacketSize] $PacketSize = [PacketSize]::Size9216
[BlockSize] $BlockSize = [BlockSize]::Size64
[bool] $HighQualityResize = $false

[ClientIO] $ClientDesktop = $null
[ClientIO] $ClientEvents = $null

ViewerSession(
[string] $ServerAddress,
[int] $ServerPort,
[SecureString] $SecurePassword,
[bool] $UseTLSv1_3,
[int] $ImageCompressionQuality
[SecureString] $SecurePassword
)
{
# Or: System.Management.Automation.Runspaces.MaxPort (High(Word))
Expand All @@ -739,8 +759,6 @@ class ViewerSession
$this.ServerAddress = $ServerAddress
$this.ServerPort = $ServerPort
$this.SecurePassword = $SecurePassword
$this.UseTLSv1_3 = $UseTLSv1_3
$this.ImageCompressionQuality = $ImageCompressionQuality
}

[void] OpenSession() {
Expand Down Expand Up @@ -918,7 +936,10 @@ class ViewerSession

$viewerExpectation = New-Object PSCustomObject -Property @{
ScreenName = $selectedScreen.Name
ImageCompressionQuality = $this.ImageCompressionQuality
ImageCompressionQuality = $this.ImageCompressionQuality
PacketSize = $this.PacketSize
BlockSize = $this.BlockSize
HighQualityResize = $this.HighQualityResize
}

if ($this.ViewerConfiguration.RequireResize)
Expand Down Expand Up @@ -1073,23 +1094,28 @@ $global:VirtualDesktopUpdaterScriptBlock = {
try
{
$packetSize = 9216 # 9KiB


# SizeOf(DWORD) * 3 (SizeOf(Desktop) + SizeOf(Left) + SizeOf(Top))
$struct = New-Object -TypeName byte[] -ArgumentList (([Runtime.InteropServices.Marshal]::SizeOf([System.Type][UInt32])) * 3)

$stream = New-Object System.IO.MemoryStream

$scene = $null
$sceneGraphics = $null

while ($true)
{
$stream = New-Object System.IO.MemoryStream
{
try
{
$buffer = New-Object -TypeName byte[] -ArgumentList 4 # SizeOf(Int32)
{
$null = $Param.Client.SSLStream.Read($struct, 0, $struct.Length)

$Param.Client.SSLStream.Read($buffer, 0, $buffer.Length)
[int32] $totalBufferSize = [BitConverter]::ToInt32($buffer, 0)
$totalBufferSize = [System.Runtime.InteropServices.Marshal]::ReadInt32($struct, 0x0)
$rectLeft = [System.Runtime.InteropServices.Marshal]::ReadInt32($struct, 0x4)
$rectTop = [System.Runtime.InteropServices.Marshal]::ReadInt32($struct, 0x8)

$stream.SetLength($totalBufferSize)

$stream.position = 0

$buffer = New-Object -TypeName Byte[] -ArgumentList $packetSize
$stream.Position = 0
do
{
$bufferSize = $stream.Length - $stream.Position
Expand All @@ -1102,22 +1128,62 @@ $global:VirtualDesktopUpdaterScriptBlock = {
} until ($stream.Position -eq $stream.Length)

$stream.Position = 0

$Param.VirtualDesktopSyncHash.VirtualDesktop.Picture.Image = [System.Drawing.Image]::FromStream($stream)

if ($stream.Length -eq 0)
{
continue
}

if (-not $scene)
{
# First Iteration
$scene = [System.Drawing.Image]::FromStream($stream)
$sceneGraphics = [System.Drawing.Graphics]::FromImage($scene)

$Param.VirtualDesktopSyncHash.VirtualDesktop.Picture.Image = $scene
}
else
{
# Next Iterations
$sceneChunk = [System.Drawing.Image]::FromStream($stream)

$sceneGraphics.DrawImage(
$sceneChunk,
[System.Drawing.Point]::New(
$rectLeft,
$rectTop
)
)

$sceneChunk.Dispose()

$Param.VirtualDesktopSyncHash.VirtualDesktop.Picture.Invalidate()
}
}
catch
{
{
break
}
finally
{
$stream.Close()
}
}
}

}
finally
{
if ($scene)
{
$scene.Dispose()
}

if ($sceneGraphics)
{
$sceneGraphics.Dispose()
}

if ($stream)
{
$stream.Close()
}

$Param.VirtualDesktopSyncHash.VirtualDesktop.Form.Close()
}
}
Expand Down Expand Up @@ -1520,6 +1586,29 @@ function Invoke-RemoteDesktopViewer
.PARAMETER AlwaysOnTop
If this switch is present, virtual desktop form will be above all other windows.
.PARAMETER BlockSize
Type: Enum
Values: Size32, Size64, Size96, Size128, Size256, Size512
Default: Size64
Description:
(Advanced) Define the screen grid block size.
Choose the block size accordingly to remote screen size / computer constrainsts (CPU / Network)
.PARAMETER PacketSize
Type: Enum
Values: Size1024, Size2048, Size4096, Size8192, Size9216, Size12288, Size16384
Default: Size9216
Description:
(Advanced) Define the network packet size for streams.
Choose the packet size accordingly to your network constrainsts.
.PARAMETER HighQualityResize
Type: Switch
Default: None
Description:
Control the quality of remote desktop resize (smoothing) if applicable.
If you lack of network speed, this option is not recommended.
.EXAMPLE
Invoke-RemoteDesktopViewer -ServerAddress "192.168.0.10" -ServerPort "2801" -SecurePassword (ConvertTo-SecureString -String "s3cr3t!" -AsPlainText -Force)
Invoke-RemoteDesktopViewer -ServerAddress "192.168.0.10" -ServerPort "2801" -Password "s3cr3t!"
Expand Down Expand Up @@ -1548,7 +1637,10 @@ function Invoke-RemoteDesktopViewer
[ValidateRange(30, 99)]
[int] $ResizeRatio = 90,

[switch] $AlwaysOnTop
[switch] $AlwaysOnTop,
[PacketSize] $PacketSize = [PacketSize]::Size9216,
[BlockSize] $BlockSize = [BlockSize]::Size64,
[switch] $HighQualityResize = $false
)

[System.Collections.Generic.List[PSCustomObject]]$runspaces = @()
Expand All @@ -1570,7 +1662,7 @@ function Invoke-RemoteDesktopViewer

Write-Banner

$null = [W.User32]::SetProcessDPIAware()
$null = [User32]::SetProcessDPIAware()

Write-Verbose "Server address: ""${ServerAddress}:${ServerPort}"""

Expand All @@ -1589,12 +1681,16 @@ function Invoke-RemoteDesktopViewer
$session = [ViewerSession]::New(
$ServerAddress,
$ServerPort,
$SecurePassword,
$UseTLSv1_3,
$ImageCompressionQuality
$SecurePassword
)
try
{
$session.UseTLSv1_3 = $UseTLSv1_3
$session.ImageCompressionQuality = $ImageCompressionQuality
$session.PacketSize = $PacketSize
$session.BlockSize = $BlockSize
$session.HighQualityResize = $HighQualityResize

if ($Resize)
{
$session.ResizeRatio = $ResizeRatio
Expand Down Expand Up @@ -1880,8 +1976,7 @@ function Invoke-RemoteDesktopViewer
}

if ($result)
{
Write-Verbose $result
{
Send-VirtualKeyboard -KeyChain $result
}
}
Expand Down
Loading

0 comments on commit a0abeff

Please sign in to comment.