Windows Embedded Shell Launcher的延迟启动

时间:2019-02-27 22:51:21

标签: windows powershell kiosk-mode

更新的查询  我正在尝试将Windows上的用户设置为“信息亭”用户。这样一来,它们就完全不受Windows功能的限制,只能访问一个应用程序。我正在使用Windows Embedded Shell启动器应用程序分配要与该用户一起运行的应用程序,到目前为止,该应用程序已经取得了成功。

我遇到的问题是,该应用程序需要设置为在启动时启动的另一软件的许可证,但是外壳程序开始快速启动,并且我要运行的应用程序在屏幕上显示许可证错误。我需要延迟启动外壳程序。

我使用Power Shell脚本来设置外壳,但是根据研究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,也要在启动时启动,或者尝试尝试确定许可程序是否已启动并在启动应用程序之前先运行,因此脚本永远不会在启动时运行,因为它正在使用一个寄存器。

是否有办法延迟此Shell的启动,或在启动时延迟运行此寄存器?我在下面添加了我用来设置外壳和基于代码的链接的脚本 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

2 个答案:

答案 0 :(得分:0)

一种更复杂的选择是检查您等待的过程是否已开始。

如果它在同一盒上运行,请使用Get-Process查看它是否启动。或Get-NetTCPConnection(如果它开始在特定端口上侦听)(如果从LAN上访问许可证服务器,则可以选择该选项)。

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"}

答案 1 :(得分:0)

我们遇到了一个非常相似的问题,昨天找到您的帖子后,我设法解决了这个问题。

我们正在将外壳启动器用于VDI亭,但遇到一个问题,即启动器会在网络建立连接之前启动VMware Horizo​​n View Client,并且会失败,并显示消息“无法解析主机名” “。

我修改了外壳启动器,以使VMware Horizo​​n View Client不再是自助服务终端用户的外壳,而是带有一些参数的powershell,这些参数打开了一个单独的脚本,该脚本循环检查网络连接,并且一旦确定已建立连接即可使其循环打开VMware Horizo​​n View Client并等待,因此,如果关闭它,它将自动重新打开。

我使用的shell启动器脚本是here

我修改的部分是:

$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
    }