Задержка запуска средства запуска Windows Embedded Shell

Обновленный запрос Я пытаюсь настроить пользователя Windows как пользователя "киоска". Это сделано для того, чтобы они были полностью заблокированы от функций Windows и имели доступ только к одному приложению. Я использую приложение запуска встроенной оболочки Windows, чтобы назначить, какое приложение запускать с этим пользователем, и до сих пор добился успеха.

Проблема, с которой я сталкиваюсь, заключается в том, что приложению требуется лицензия от другого программного обеспечения, которое настроено на запуск при запуске, но оболочка запускается быстро, и приложение, которое я хочу запустить, отображает ошибку лицензии на экране. Мне нужно отложить запуск оболочки.

Я использую сценарий Power Shell для настройки оболочки, но из исследования, -to-custom-shell?forum=quebeccomponentsforum" rel="nofollow noreferrer">https://social.msdn.microsoft.com/Forums/en-US/d0d9fc55-ab03-43e7-9c3a-10ce85060386/how-to- custom-shell?forum=quebeccomponentsforum, этот сценарий просто устанавливает значение реестра HKLM\Software\Microsoft\Windows NT\CurrentVersion\WinlogonShell= "something.exe".

Поэтому при запуске, даже если я устанавливаю задержку Start-Sleep или пытаюсь выяснить, запущена ли и работает ли программа лицензирования перед запуском приложения, сценарий никогда не запускается при запуске, поскольку он использует регистр.

Есть ли способ отложить запуск этой оболочки или отложить запуск этого регистра при запуске? Ниже я добавил скрипт, который использую для настройки оболочек и ссылок, на основе кода которых я создал https://docs.microsoft.com/en-us/windows/configuration/kiosk-shelllauncher

     #----- Function to Check if shell launcher license is enabled ------#
    function Check-ShellLauncherLicenseEnabled
    {
        [string]$source = @"
    using System;
    using System.Runtime.InteropServices;

    static class CheckShellLauncherLicense
    {
        const int S_OK = 0;

        public static bool IsShellLauncherLicenseEnabled()
        {
            int enabled = 0;

            if (NativeMethods.SLGetWindowsInformationDWORD("EmbeddedFeature-ShellLauncher-Enabled", out enabled) != S_OK) {
                enabled = 0;
            }
            return (enabled != 0);
        }

        static class NativeMethods
        {
            [DllImport("Slc.dll")]
            internal static extern int SLGetWindowsInformationDWORD([MarshalAs(UnmanagedType.LPWStr)]string valueName, out int value);
        }

    }
    "@

        $type = Add-Type -TypeDefinition $source -PassThru

        return $type[0]::IsShellLauncherLicenseEnabled()
    }

    [bool]$result = $false

    $result = Check-ShellLauncherLicenseEnabled
    "`nShell Launcher license enabled is set to " + $result
    if (-not($result))
    {
        "`nThis device doesn't have required license to use Shell Launcher"
        exit
    }

    $COMPUTER = "localhost"
    $NAMESPACE = "root\standardcimv2\embedded"

    # Create a handle to the class instance so we can call the static methods.
    try {
        $ShellLauncherClass = [wmiclass]"\\$COMPUTER\${NAMESPACE}:WESL_UserSetting"
        } catch [Exception] {
        write-host $_.Exception.Message; 
        write-host "Make sure Shell Launcher feature is enabled"
        exit
        }


    #-----Function to retrieve the SID for the user account on the machine-----#

    function Get-UsernameSID($AccountName) {

        $NTUserObject = New-Object System.Security.Principal.NTAccount($AccountName)
        $NTUserSID = $NTUserObject.Translate([System.Security.Principal.SecurityIdentifier])

        return $NTUserSID.Value
    }

    #---- Get the SID's for accounts-----# 

    $Operator_SID = Get-UsernameSID("Operator")
    $Admin_SID = Get-UsernameSID("Administrator")

    #----- Define actions to take when the shell program exits -----#

    $restart_shell = 0
    $restart_device = 1
    $shutdown_device = 2


    #----- Set Default Shell ----#
    # This example sets the command prompt as the default shell, and restarts the device if the command prompt is closed. 

    # $ShellLauncherClass.SetDefaultShell("cmd.exe", $restart_device)

    #----- Default Shell Display -----#
    # Display the default shell to verify that it was added correctly.

    $DefaultShellObject = $ShellLauncherClass.GetDefaultShell()

    "`nDefault Shell is set to " + $DefaultShellObject.Shell + " and the default action is set to " + $DefaultShellObject.defaultaction

    # ----- Operator Shell Set -----#
     $ShellLauncherClass.SetCustomShell($Operator_SID, "C:\Components\application.exe", ($null), ($null), $restart_shell)       
   # ----- Admin Shell Set -----#
    # Set Explorer as the shell for administrator.

     $ShellLauncherClass.SetCustomShell($Admin_SID, "explorer.exe")

    #-----Enable the Shell Launcher -----#

    $ShellLauncherClass.SetEnabled($TRUE)

    $IsShellLauncherEnabled = $ShellLauncherClass.IsEnabled()

    "`nEnabled is set to " + $IsShellLauncherEnabled.Enabled

    #-----Remove Custom Shell -----#
    # To remove a user shell, comment out the $ShelllauncherClass.SetCustomShell command and uncomment the required RemoveCustomShell command

    # $ShellLauncherClass.RemoveCustomShell($Admin_SID)

    # $ShellLauncherClass.RemoveCustomShell($Operator_SID)

    #----- Disable Shell Launcher -----# Uncomment to use

    # $ShellLauncherClass.SetEnabled($FALSE)

    # $IsShellLauncherEnabled = $ShellLauncherClass.IsEnabled()

    # "`nEnabled is set to " + $IsShellLauncherEnabled.Enabled

    #----- Display all the custom shells defined -----#

    "`nCurrent settings for custom shells:"
    Get-WmiObject -namespace $NAMESPACE -computer $COMPUTER -class WESL_UserSetting | Select Sid, Shell, DefaultAction

person ConfusedDuck    schedule 27.02.2019    source источник
comment
когда я запускаю скрипт, который имеет Start-Sleep в качестве 1-й команды... оставшаяся часть скрипта приостанавливается до тех пор, пока командлет не достигнет своего тайм-аута.   -  person Lee_Dailey    schedule 28.02.2019
comment
Итак, вы предлагаете поставить Start-Sleep прямо в начало скрипта, чтобы отложить его выполнение при запуске?   -  person ConfusedDuck    schedule 28.02.2019
comment
Что означает запуск? Что-то, что запускается, когда пользователь входит в систему? Или запуск скрипта по запросу? Как отмечает @Lee_Dailey, Start-Sleep по замыслу ожидает синхронно указанное количество секунд, прежде чем продолжить выполнение. Поскольку вы говорите, что это просто задерживает, но это то, для чего предназначен Start-Sleep, уточните свои требования, непосредственно обновив свой вопрос (не используйте комментарии). Как правило, лучше не полагаться на фиксированную задержку, а вместо этого (периодически) проверять, достигнуты ли желаемые состояния.   -  person mklement0    schedule 28.02.2019
comment
@ConfusedDuck - да, размещение командлета прямо в начале задержит весь скрипт. я использую его в нескольких сценариях, чтобы приостановить сценарий, чтобы можно было прочитать сообщение - 30-секундная пауза подходит для чтения простого сообщения.   -  person Lee_Dailey    schedule 28.02.2019


Ответы (2)


Гораздо более сложным вариантом было бы проверить, что процесс, которого вы ждете, начался.

Если он работает на том же компьютере, используйте Get-Process, чтобы проверить, работает ли он. Или Get-NetTCPConnection, если он начинает прослушивать определенный порт (если доступ к серверу лицензий осуществляется через локальную сеть, то вы должны выбрать именно этот вариант).

do {
    sleep 10 
    $proc = Get-Process -Name licsrv -ea silentlycontinue
} until ($proc)

Start-process ...

Возможно, вы также захотите иметь счетчик циклов, чтобы вы могли выполнять X циклов и убегать, если это занимает слишком много времени.

$loop = 0
do {
    sleep 10 
    $proc = Get-Process -Name licsrv -ea silentlycontinue
    $loop++
} until ($proc -or $loop -ge 60) #wait until proc runs or 10 mins
If ($proc) {Start-process ... } # the process is running, not loop termination
Else {Throw "some error message"}
person LeeM    schedule 28.02.2019

У нас была очень похожая проблема, которую мне удалось решить вчера после того, как я нашел ваш пост.

Мы используем средство запуска оболочки для киоска VDI, но столкнулись с проблемой, когда средство запуска запускало клиент VMware Horizon View до того, как сеть установила соединение, и это завершалось ошибкой с сообщением «Не удалось разрешить имя хоста».

Я изменил средство запуска оболочки, так что VMware Horizon View Client больше не был оболочкой для пользователя киоска, а вместо этого был powershell с параметрами, которые открывали отдельный скрипт, который зацикливал проверку сетевого подключения, и как только он установил, что подключение было установлено, он зациклился открытие клиента VMware Horizon View и ожидание, чтобы, если он был закрыт, он автоматически снова открылся.

Сценарий запуска оболочки, который я использовал, находится здесь.

Часть, которую я изменил:

$kiosk_app_path = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy ByPass -windowstyle hidden -file C:\Scripts\DelayedShellLauncher.ps1"

# Set Powershell as the shell for "Cashier".
$ShellLauncherClass.SetCustomShell($Cashier_SID, $kiosk_app_path, ($null), ($null))

А вот скрипт ps1, который я написал:

do {
    Write-Host "Waiting for network connection..."
    } until(Test-Connection 8.8.8.8 -Quiet -count 1)

while ($true) {
    Start-Process -FilePath "C:\Program Files (x86)\VMware\VMware Horizon View Client\vmware-view.exe" -wait
    }
person Kyan    schedule 19.12.2019