Scénario
Deux approches différentes qui ouvrent toutes deux une url dans un navigateur cessent de fonctionner lorsque je les place dans un job dans powershell, mais cessent de fonctionner si je les place dans une méthode d'une classe/objet. J'ai vérifié que l'objet dans le job est exécuté correctement car il exécute également une commande de copie dont je peux voir le résultat apparaître.
Code
Il s'agit du code de travail sans qu'il soit placé dans un objet :
# 5. Start job and execute a method of the object
Start-Job -Name ListStuffOnTable -ScriptBlock {
# attempt 1 opening default browser
$authUrl = "http://superuser.com"
Write-Host "visiting url="$authUrl
(New-Object -com Shell.Application).Open($authUrl)
# attempt 2 opening internet explorer
$ie = new-object -com "InternetExplorer.Application"
$ie.visible = $true
$ie.navigate("http://superuser.com")
}
Write-Host "Created job"
# Give the job 10 seconds to create a list of entries.
Start-Sleep -Milliseconds 10000
Write-Host "Running askSync"
#Run command that starts an infinite loop untill the browser is opened by the job.
wsl /home/testlinuxname/maintenance/./askSync.sh
Write-Host "Running stopjob"
# 6. Stop the job to get the data out.
Get-Job -Name ListStuffOnTable | Stop-Job
# 7. Verify it exists and functions correctly:
Write-Host "`n Deleting job"
# 8. Delete the job for correct bookkeeping:
Get-Job -Name ListStuffOnTable | Remove-Job
Et pour être complet, voici le code qui n'ouvre pas l'url intégrée dans l'objet :
# 5. Start job and execute a method of the object
Start-Job -Name ListStuffOnTable -ScriptBlock {
# 5.1 first write the class
class GCalAccess{
# Properties
[String] $urlSourcePath
[String] $urlDestPath
[String] $urlFilename
[String] $absUrlSourceFilePath
[String] $absUrlDestFilePath
[HardCoded] $hardCoded
[String] $authUrl
[String] $defaultBrowserLocation
[String] $absUrlWinDestFilePath
# constructor
GCalAccess([HardCoded] $hardCoded)
{
$this.hardCoded = $hardCoded
Write-Host $this.hardCoded.getWindowsCurrentPath()
# create the source and destination of the file that containts the url (url.txt)
# it is coppied from inside the wsl to this folder, so that powershell can read it and open the url in browser
$this.urlSourcePath = "/home/"+"testlinuxname"+"/"+$this.hardCoded.getmaintenanceFolderName()+"/"+$this.hardCoded.getGCalSyncFolderName()+"/"
$this.urlDestPath = $this.hardCoded.getLinuxCurrentPath()+"/"
$this.urlFilename = $this.hardCoded.getAuthUrlFilename()
$this.absUrlSourceFilePath=$this.urlSourcePath+$this.urlFilename
$this.absUrlDestFilePath=$this.urlDestPath+$this.urlFilename
$this.absUrlWinDestFilePath = $this.hardCoded.getWindowsCurrentPath()+"/"+$this.urlFilename
Write-Host "WinPath="$this.absUrlWinDestFilePath
Write-Host $this.hardCoded.getWindowsCurrentPath()
Write-Host $this.hardCoded.getLinuxCurrentPath()
Write-Host "Url source file path = "$this.absUrlSourceFilePath
Write-Host "Url destination file path = "$this.absUrlDestFilePath
}
# Infinite loop that Scans the existance of the file
scanUrlFile(){
[boolean] $foundUrl = $false
# first copy the fail, regardless of whether it exists, then check if it is copied:
while(!$foundUrl)
{
$this.copyUrl()
if (Test-Path $this.absUrlWinDestFilePath -PathType leaf)
{
Write-Host "FOUND Url"
#do some stuff
$foundUrl = $true
}
}
# exit
# while(!$this.foundUrl())
# {
# # sleep 0.3 seconds
# Write-Host "Didn't find it yet."
# Start-Sleep -Milliseconds 300
# }
}
# Checks whether url file is found in the wsl
[boolean] foundUrl()
{
# create wsl command that checks whether the file exists
$command = "ls "+$this.absUrlSourceFilePath+" && echo FoundUrlFile"
Write-Host "Command="+$command
$output = bash "-c" $command
# evaluate the output of the command to see if it found (null if not found, ends in "FoundUrlFile" if it is found)
if($output-like "*FoundUrlFile"){
Write-Host "Output="$output"..."
return $true
}else {
return $false
}
}
# copy the file that contains the url
copyUrl() {
# create copy command
Write-Host "pathSource="$this.absUrlSourceFilePath
Write-Host "pathDest="$this.absUrlDestFilePath
[String] $command = "sudo cp "+$this.absUrlSourceFilePath+" `""+$this.absUrlDestFilePath+"`""
$output = bash "-c" $command
Write-Host $output
}
readUrlFromFile(){
$windowsUrlFilePath =$this.hardCoded.getWindowsCurrentPath()+"/"+$this.urlFilename
Write-Host "windowsUrlFilePath="$windowsUrlFilePath
$this.authUrl = Get-Content $windowsUrlFilePath -First 1
}
# open link to prefered browser
openUrlInBrowser(){
Write-Host "visiting url="$this.authUrl
(New-Object -com Shell.Application).Open($this.authUrl)
$ie = new-object -com "InternetExplorer.Application"
$ie.visible = $true
$ie.navigate("http://www.google.com")
}
# deletes the copied file with the authorization url after use
cleanUpWindowsUrlFileCopy(){
}
# TODO: CLick >nextnextnext if website allows it.
#############################ASSISTING FUNCTIONS#################
# returns the integer index in the url string of the occurence of "$scope"
[int] findIndexOfKeyword([String] $url){
return $url.IndexOf("&scope")
}
}
class HardCoded {
# object properties/fields
[String] $windowsCurrentPath
[String] $linuxCurrentPath
# create relative folder names
[String] $maintenanceFolderName = "maintenance"
[String] $gCalSyncFolderName = "gCal"
# create hardcoded localHost url for google calendar sync
[String] $authUrlFilePath = "/home/"+$this.linuxUsername+"/"+$this.getmaintenanceFolderName()+"/"+$this.getGCalSyncFolderName+"/"
[String] $authUrlFilename = "url.txt"
HardCoded () {
# set current paths
$this.windowsCurrentPath = $this.getCurrentPath()
$this.linuxCurrentPath = $this.convertWinPathToLinuxPath($this.windowsCurrentPath)+"/"
}
# convert Windows path to linux path:
[String] convertWinPathToLinuxPath([String] $winPath) {
$linuxPath = (($winPath -replace "\\","/") -replace ":","").Trim("/")
# convert drive letter to lowercase:
$linuxPath = $linuxPath.Substring(0,1).ToLower()+$linuxPath.Substring(1)
$linuxPath = "/mnt/"+$linuxPath
return $linuxPath
}
# return linux format of current path
[String] getCurrentPath() {
[String] $winPath = Split-Path -parent $PSCommandPath
return $winPath
}
# Getters
[String] getmaintenanceFolderName() {
return $this.maintenanceFolderName
}
# Getters
[String] getGCalSyncFolderName() {
return $this.gCalSyncFolderName
}
# Getters
[String] getAutoInstallTwProjectName() {
return $this.autoInstallTwProjectName
}
# Getters
[String] getDefaultLocalHostname() {
return $this.defaultLocalHostname
}
# Getters
[String] getWindowsCurrentPath() {
return $this.windowsCurrentPath
}
# Getters
[String] getLinuxCurrentPath() {
return $this.linuxCurrentPath
}
# Getters
[String] getAuthUrlFilePath() {
return $this.authUrlFilePath
}
# Getters
[String] getAuthUrlFilename() {
return $this.authUrlFilename
}
}
#Create objects that are used
[HardCoded] $hardCoded = [HardCoded]::new()
[GCalAccess] $gCalAccess = [GCalAccess]::new($hardCoded)
# Create a background job to scan for url file
# scan for the url file to emerge
$gCalAccess.scanUrlFile()
#$gCalAccess.copyUrl()
$gCalAccess.readUrlFromFile()
$gCalAccess.openUrlInBrowser()
}
Write-Host "Created job"
# Give the job 10 seconds to create a list of entries.
Start-Sleep -Milliseconds 10000
Write-Host "Running askSync"
#Run command that displays the url (and indirectly generates the url file) inside the installer
wsl /home/testlinuxname/maintenance/./askSync.sh
Write-Host "Running stopjob"
# 6. Stop the job to get the data out.
Get-Job -Name ListStuffOnTable | Stop-Job
# 7. Verify it exists and functions correctly:
Write-Host "`n Deleting job"
# 8. Delete the job for correct bookkeeping:
Get-Job -Name ListStuffOnTable | Remove-Job
Pregunta
Pourquoi le code intégré dans un objet méthode n'ouvre-t-il pas un navigateur ?
Solution
La solution à mon problème xy est de mettre le code d'ouverture du site web en dehors de l'objet, mais j'aimerais mieux comprendre pourquoi powershell se comporte de cette façon (ou découvrir que j'ai fait une erreur que je n'ai pas encore vue).