batocera-linux/batocera-emulationstation

.ps1 launch problem in scripts/* ES folder

Closed this issue · 7 comments

Concerned project

Retrobat

Distribution Version

Retrobat V6

Architecture

Windows 11 pro

Issue description

Hello,
I adapted my python script in ps1 but it doesn't launch at all. On the command line from the /scripts/game-selected folder it launches fine.
For example:
.\run.ps1 "mame" "C:/RetroBat/roms/mame/cotton2.zip" "Cotton 2: Magical Night Dreams"
But from ES/Retrobat onwards, when I change game, I see a split-second window appear and disappear.
Perhaps the way the scripts are launched has changed?
Thanks

Logs and data


Function Load-Config {
    try {
        $configIniFilePath = "C:\RetroBatV6\plugins\MarqueeManager\config.ini"
        Write-Host "Checking for config file at: $configIniFilePath"

        if (-Not (Test-Path $configIniFilePath)) {
            Write-Error "Fichier de configuration non trouvé at $configIniFilePath."
            exit 1
        }

        $iniContent = Get-Content $configIniFilePath -Raw
        $config = @{}
        $currentSection = ""

        foreach ($line in ($iniContent -split "`n")) {
            $trimmedLine = $line.Trim()
            if ($trimmedLine.StartsWith("[") -and $trimmedLine.EndsWith("]")) {
                $currentSection = $trimmedLine.Substring(1, $trimmedLine.Length - 2)
                $config[$currentSection] = @{}
            } elseif ($trimmedLine -match '^\s*(\S+)\s*=\s*(.*)') {
                $key, $value = $matches[1], $matches[2]
                $config[$currentSection][$key] = $value
            }
        }

        Write-Host "Successfully loaded config from $configIniFilePath"
        return $config
    }
    catch {
        Write-Error "Error loading configuration file: $_"
        exit 1
    }
}


Function Send-Event {
    param ($event, $params, $serverUrl, $currentTime)
    try {
        # Construct the query string with params
        $queryParts = foreach ($key in $params.Keys) {
            "$key=$([System.Uri]::EscapeDataString($params[$key]))"
        }

        # Add timestamp at the end
        $queryParts += "timestamp=$currentTime"
        $query = $queryParts -join "&"

        # Construct the full URI
        $fullUri = "${serverUrl}?event=$event&$query"
        Write-Host "Requesting URI: $fullUri"  # For debugging

        $response = Invoke-WebRequest -Uri $fullUri -UseBasicParsing

        # Uncomment to see the response text
        # Write-Host $response.Content
    }
    catch {
        Write-Host "Erreur lors de l'envoi de l'événement : $_"
    }
}


Function Get-CurrentDirectoryEvent {
    $currentDirEvent = Split-Path (Get-Location) -Leaf
    Write-Host "Current Directory Event: $currentDirEvent"  # For debugging
    return $currentDirEvent
}

$epochStart = [datetime]"1970-01-01T00:00:00Z"
$current_time = (New-TimeSpan -Start $epochStart -End ([datetime]::UtcNow)).TotalSeconds
$config = Load-Config

$configHost = $config['Settings']['host']
$configPort = $config['Settings']['port']

if (-not $configHost) { Write-Host "Host value not found in configuration." }
if (-not $configPort) { Write-Host "Port value not found in configuration." }

$server_url = "http://${configHost}:${configPort}"
Write-Host "Host URL: $server_url"

$event = Get-CurrentDirectoryEvent
Write-Host "Event: $event"  # For debugging

# Use $args directly to get the arguments passed to the script
$params = @{}
for ($i = 0; $i -lt $args.Count; $i++) {
    $params["param$($i + 1)"] = $args[$i]
}

Send-Event -event $event -params $params -serverUrl $server_url -currentTime $current_time

Ok, I've just been told that you can't directly launch a ps1 on windows, which doesn't allow execution.
You need to bypass it...

Aynshe helped me understand. I had associated the .ps1 files with my IDE. Sorry about that.
What is certain is that you have to go through an intermediate .bat to authorize the execution of a ps1, so you can't run it directly.

@echo off
powershell -ExecutionPolicy Bypass -File "..\run.ps1" %*

It's ok. Thanks.

You're right, there's a problem launching .ps1 scripts without using a bat file first.
I'll make a fix for this.

Unfortunately, it will probably not solve your initial problem of lacenty as powershell is very very very long to initialize too.

I have created 3 "scripts", one with .bat, one with .ps1, one with c# exe.
They only display the current time in a messagebox to mesure the elapsed time between queuing script call in EmulationStation, and REAL execution time in the script code :

Using a batch file :
the message seems to appear amost instantly : it takes 191 milliseconds.

16:47:25.674 DEBUG queuing: H:/[Emulz]/emulationstation/.emulationstation/scripts/test.bat system-selected "fbneo"
16:47:25.699 DEBUG executing: H:/[Emulz]/emulationstation/.emulationstation/scripts/test.bat system-selected "fbneo"

image

Using powershell
it takes 1,113 seconds to show the message :

16:51:48.906 DEBUG queuing: powershell H:/[Emulz]/emulationstation/.emulationstation/scripts/test.ps1 system-selected "atari7800"
16:51:48.933 DEBUG executing: powershell H:/[Emulz]/emulationstation/.emulationstation/scripts/test.ps1 system-selected "atari7800"

image

With a basic C# Windows Forms application.
As you can see, it's almost instant as it takes only 69 milliseconds to display the message !!!!!

17:00:06.308 DEBUG queuing: H:/[Emulz]/emulationstation/.emulationstation/scripts/WindowsFormsApplication1.exe system-selected "mess"
17:00:06.330 DEBUG executing: H:/[Emulz]/emulationstation/.emulationstation/scripts/WindowsFormsApplication1.exe system-selected "mess"

image

I did not try C++ but it would probably be the fastest.
I did not try Python but it would probably be the slowest ( exceeding 1 second )

So my advice to reduce perceived latency, is to try C# or C++.

Thanks for all the tests. You're absolutely right, .bat are very efficient and I'm going to use them from now on. Unfortunately, you can't attack a URL directly with them, so I'm going to use an intermediate file that I'll listen to.
Thank you for this project, the complexity and power of which I can now appreciate.

"I did not try Python but it would probably be the slowest ( exceeding 1 second )" : for sure, no. very strange assumption.

as a comparison, time to load python on linux is 0.068 seconds.

$ time python3 </dev/null
real 0m0,068s
user 0m0,055s
sys 0m0,014s
$

In fact, Fabricecaruso was talking about a python script compiled for windows with Pyinstaller, and indeed it takes a second or so, a little less to launch. He's got a point there.
It's true that launching python directly from the command line is very fast, but not everyone has python installed on Windows.
Thanks for your analysis nadenislamarre, because if one day someone adapts my script for linux, I can see that it will be very fast.