Evan's Blog
EvanZhu0721 / 公开仓库

SBMS

镜像已同步

SBMS complete the calculation rules for the default logical desktop topology relationship and the physical dimensions of the displays in the Windows multi-screen collaboration system.

上游 GitHub
READ-ONLY MIRROR

README、源码与 Release 已保存到本站;源码视图固定到 commit bd87fa1e。

main/ root / installer/tests
bd87fa1e· 固定源码快照
installer/tests/launch-entry-contract.Tests.ps18.1 KB
1$ErrorActionPreference = 'Stop'
2Set-StrictMode -Version Latest
3
4$repository = [IO.Path]::GetFullPath(
5 (Join-Path $PSScriptRoot '..\..')
6)
7$installerScript = Join-Path $repository 'installer\SBMS.iss'
8$maintenanceScript = Join-Path $repository 'installer\maintenance.ps1'
9$launchBroker = Join-Path $repository 'src\launch_broker.rs'
10
11function Get-InnoSection {
12 param(
13 [Parameter(Mandatory)]
14 [string]$Source,
15
16 [Parameter(Mandatory)]
17 [string]$Name
18 )
19
20 $match = [regex]::Match(
21 $Source,
22 "(?ms)^\[$([regex]::Escape($Name))\]\s*(?<body>.*?)(?=^\[|\z)"
23 )
24 if (-not $match.Success) {
25 throw "Inno Setup section [$Name] was not found."
26 }
27 $match.Groups['body'].Value
28}
29
30Describe 'SBMS launch entry contract' {
31 BeforeAll {
32 $script:installerSource = [IO.File]::ReadAllText(
33 $installerScript,
34 [Text.Encoding]::UTF8
35 )
36 $script:maintenanceSource = [IO.File]::ReadAllText(
37 $maintenanceScript,
38 [Text.Encoding]::UTF8
39 )
40 $script:launchBrokerSource = [IO.File]::ReadAllText(
41 $launchBroker,
42 [Text.Encoding]::UTF8
43 )
44
45 $dispatchMarker = 'switch ($Action) {'
46 $dispatchIndex = $script:maintenanceSource.LastIndexOf(
47 $dispatchMarker,
48 [StringComparison]::Ordinal
49 )
50 if ($dispatchIndex -lt 0) {
51 throw 'maintenance.ps1 action dispatcher was not found.'
52 }
53 $definitions = $script:maintenanceSource.Substring(0, $dispatchIndex)
54 $script:loadRoot = Join-Path $TestDrive 'install-root'
55 New-Item -ItemType Directory -Path $script:loadRoot -Force | Out-Null
56 . ([scriptblock]::Create($definitions)) `
57 -Action Stop `
58 -InstallRoot $script:loadRoot
59 }
60
61 It 'marks the Start menu launch as an explicit open request' {
62 $icons = Get-InnoSection `
63 -Source $script:installerSource `
64 -Name 'Icons'
65 $shortcut = @(
66 $icons -split "`r?`n" |
67 Where-Object {
68 $_ -match '(?i)^\s*Name:\s*"\{group\}\\SBMS"\s*;'
69 }
70 )
71
72 $shortcut.Count | Should Be 1
73 $shortcut[0] | Should Match (
74 '(?i);\s*Filename:\s*"\{app\}\\sbms-tray\.exe"\s*;' +
75 '\s*Parameters:\s*"--open"(?:\s*;|\s*$)'
76 )
77 }
78
79 It 'registers an interactive highest-privilege background tray task' {
80 $script:mockTaskAction =
81 [Microsoft.Management.Infrastructure.CimInstance]::new('MSFT_TaskAction')
82 $script:mockTrigger =
83 [Microsoft.Management.Infrastructure.CimInstance]::new('MSFT_TaskTrigger')
84 $script:mockPrincipal =
85 [Microsoft.Management.Infrastructure.CimInstance]::new('MSFT_TaskPrincipal')
86 $script:mockSettings =
87 [Microsoft.Management.Infrastructure.CimInstance]::new('MSFT_TaskSettings')
88 $script:startedProcess = [pscustomobject]@{ Id = 4242 }
89 $script:processScan = 0
90 $script:taskRegistered = $false
91 Mock Assert-InstallIdentity {
92 [pscustomobject]@{ Sid = 'S-1-5-21-test' }
93 }
94 Mock Get-ScheduledTask { $null }
95 Mock New-ScheduledTaskAction { $script:mockTaskAction }
96 Mock New-ScheduledTaskTrigger { $script:mockTrigger }
97 Mock New-ScheduledTaskPrincipal { $script:mockPrincipal }
98 Mock New-ScheduledTaskSettingsSet { $script:mockSettings }
99 Mock Register-ScheduledTask {
100 $marker = [System.Threading.Mutex]::OpenExisting('Local\SBMS-Manual-Launch-Broker-7EB4D7A8')
101 $marker.Dispose()
102 $script:taskRegistered = $true
103 }
104 Mock Start-ScheduledTask {}
105 $script:readyChecks = 0
106 Mock Test-SbmsTrayReady {
107 $marker = [System.Threading.Mutex]::OpenExisting('Local\SBMS-Manual-Launch-Broker-7EB4D7A8')
108 $marker.Dispose()
109 $script:readyChecks++
110 $script:readyChecks -ge 2
111 }
112 Mock Start-Sleep {}
113 Mock Get-InstalledSbmsProcesses {
114 $script:processScan++
115 if ($script:taskRegistered) {
116 $script:startedProcess
117 }
118 }
119
120 Install-SbmsTask
121
122 Assert-MockCalled New-ScheduledTaskAction -Times 1 -Exactly `
123 -ParameterFilter {
124 $Execute -eq $script:tray -and
125 $Argument -ceq '--background' -and
126 $WorkingDirectory -eq $script:loadRoot
127 }
128 Assert-MockCalled New-ScheduledTaskTrigger -Times 1 -Exactly `
129 -ParameterFilter {
130 $AtLogOn -and $User -eq 'S-1-5-21-test'
131 }
132 Assert-MockCalled New-ScheduledTaskPrincipal -Times 1 -Exactly `
133 -ParameterFilter {
134 $UserId -eq 'S-1-5-21-test' -and
135 $LogonType -eq 'Interactive' -and
136 $RunLevel -eq 'Highest'
137 }
138 Assert-MockCalled New-ScheduledTaskSettingsSet -Times 1 -Exactly `
139 -ParameterFilter {
140 $AllowStartIfOnBatteries -and
141 $DontStopIfGoingOnBatteries -and
142 $ExecutionTimeLimit -eq [TimeSpan]::Zero -and
143 $MultipleInstances.ToString() -eq 'IgnoreNew'
144 }
145 Assert-MockCalled Register-ScheduledTask -Times 1 -Exactly `
146 -ParameterFilter {
147 $TaskPath -eq '\SBMS\' -and
148 $TaskName -eq 'Tray-7EB4D7A8-16A9-4B6F-82E3-31A77BC81B6A' -and
149 $Action.Count -eq 1 -and
150 [object]::ReferenceEquals($Action[0], $script:mockTaskAction) -and
151 $Trigger.Count -eq 1 -and
152 [object]::ReferenceEquals($Trigger[0], $script:mockTrigger) -and
153 [object]::ReferenceEquals($Principal, $script:mockPrincipal) -and
154 [object]::ReferenceEquals($Settings, $script:mockSettings)
155 }
156 Assert-MockCalled Start-ScheduledTask -Times 1 -Exactly `
157 -ParameterFilter {
158 $TaskPath -eq '\SBMS\' -and
159 $TaskName -eq 'Tray-7EB4D7A8-16A9-4B6F-82E3-31A77BC81B6A'
160 }
161 Assert-MockCalled Start-Sleep -Times 1 -Exactly `
162 -ParameterFilter { $Milliseconds -eq 200 }
163 $script:processScan | Should Be 3
164 { [System.Threading.Mutex]::OpenExisting('Local\SBMS-Manual-Launch-Broker-7EB4D7A8') } | Should Throw
165 }
166
167 It 'accepts the legacy empty task arguments during an upgrade' {
168 Mock Get-ScheduledTask {
169 [pscustomobject]@{
170 Actions = @(
171 [pscustomobject]@{
172 Execute = $script:tray
173 Arguments = ''
174 WorkingDirectory = $script:loadRoot
175 }
176 )
177 }
178 }
179
180 $task = Get-VerifiedTask -Path '\SBMS\' -Name 'test'
181
182 $task | Should Not BeNullOrEmpty
183 }
184
185 It 'rejects an unexpected action count before indexing the task action' {
186 Mock Get-ScheduledTask {
187 [pscustomobject]@{ Actions = @() }
188 }
189
190 $failure = $null
191 try {
192 Get-VerifiedTask -Path '\SBMS\' -Name 'test'
193 }
194 catch {
195 $failure = $_
196 }
197
198 $failure | Should Not BeNullOrEmpty
199 $failure.Exception.Message | Should Match 'Scheduled task collision'
200 }
201
202 It 'keeps the registered task name identical in Rust and PowerShell' {
203 $rustName = [regex]::Match(
204 $script:launchBrokerSource,
205 '(?ms)pub const REGISTERED_TASK_NAME:\s*&str\s*=\s*r"([^"]+)";'
206 )
207 $powerShellPath = [regex]::Match(
208 $script:maintenanceSource,
209 '(?m)^\$taskPath\s*=\s*''([^'']+)'''
210 )
211 $powerShellName = [regex]::Match(
212 $script:maintenanceSource,
213 '(?m)^\$taskName\s*=\s*''([^'']+)'''
214 )
215
216 $rustName.Success | Should Be $true
217 $powerShellPath.Success | Should Be $true
218 $powerShellName.Success | Should Be $true
219 ($powerShellPath.Groups[1].Value + $powerShellName.Groups[1].Value) |
220 Should Be $rustName.Groups[1].Value
221 }
222}
223