Je note ce que @Allan a indiqué dans son commentaire en dessous de votre question.
Bien que je n'obtienne pas un délai aussi long que 10-15 secondes en utilisant la ligne de commande, je trouve qu'elle est manifestement et constamment plus lente (de quelques secondes) que le fait de cliquer sur l'icône WiFi. Je ne connais pas les opérations sous-jacentes effectuées par networksetup
Mais je me demande s'il n'effectue pas un balayage du réseau à chaque fois qu'une demande est faite pour rejoindre un nouveau réseau, ce qui pourrait expliquer le délai. Les délais d'analyse du réseau peuvent être influencés par de nombreux facteurs, de sorte que ce délai varierait probablement d'un utilisateur à l'autre dans des environnements différents. Il ne s'agit toutefois que d'une hypothèse.
J'aimerais pouvoir créer un applescript qui clique manuellement pour changer de réseau Wi-Fi.
Je vais vous donner deux scripts.
1. Service-scripting avec AppleScriptObjC
Le premier script utilise AppleScriptObjC pour s'interfacer directement avec le système et contrôler l'interface WiFi. Un résumé rapide, que je développe ci-dessous :
- + Robuste/fiable
- + Plus rapide que
networksetup
- + Plus besoin de saisir manuellement les mots de passe
- + Pas de perturbations visuelles à l'écran ; fonctionne en arrière-plan
- Plus lent que de cliquer sur l'icône WiFi
-
SSID insensible à la casse, correspondance avec des phrases entières (modifiable)
use framework "CoreWLAN"
property this : a reference to current application
property nil : a reference to missing value
property _1 : a reference to reference
property CWWiFiClient : a reference to CWWiFiClient of this
property NSPredicate : a reference to NSPredicate of this
to joinNetwork given name:ssid as text, password:pw as text : missing value
local ssid, pw
set |?| to NSPredicate's predicateWithFormat:("self.ssid ==[c] %@") ¬
argumentArray:{ssid}
tell CWWiFiClient's sharedWiFiClient()'s interface()
its setPower:true |error|:nil
set networks to {}
tell cachedScanResults() to if it missing value then ¬
set networks to filteredSetUsingPredicate_(|?|)
if the number of networks = 0 then set networks to ¬
(its scanForNetworksWithName:ssid |error|:nil)
set network to (allObjects() in networks)'s firstObject()
its associateToNetwork:network |password|:pw |error|:_1
set [success, E] to the result
if E missing value then return ¬
E's localizedDescription() ¬
as text
success
end tell
end joinNetwork
Vous appelleriez alors la fonction joinNetwork
à partir de votre script comme suit :
joinNetwork given name:"my network ssid", password:"Passw0rd1"
Ce script sera robuste et fiable (sauf erreur humaine de ma part, que je corrigerai si vous trouvez un bug que j'ai négligé lors des tests). Il utilise de préférence les résultats de l'analyse mis en cache pour se connecter aux réseaux ; si aucun n'est disponible, ou si le SSID spécifié n'apparaissait pas lorsque les résultats de l'analyse ont été mis en cache pour la dernière fois, il effectuera une nouvelle analyse du réseau. Par conséquent, si mon hypothèse concernant networksetup
est un facteur contributif, ce script sera plus rapide que la ligne de commande sur la majorité des exécutions, mais peut prendre le même temps sur l'exécution occasionnelle lorsque l'on est forcé d'effectuer un balayage.
L'un des avantages est que, comme vous pouvez spécifier un mot de passe réseau lors de l'appel de la fonction joinNetwork
vous n'aurez pas à le saisir manuellement lorsque vous rejoindrez un nouveau réseau.
Le SSID spécifié par le name
est insensible à la casse dans les deux scripts ; le mot de passe, évidemment, ne l'est pas. Le scripts ci-dessus a choisi d'effectuer une correspondance de phrase complète sur le SSID, c'est-à-dire que "mon réseau" ne rejoindra jamais un réseau appelé "mon réseau" ; le scripts ci-dessous a choisi d'effectuer une correspondance floue, c'est-à-dire que "réseau" rejoindra potentiellement "mon réseau" ou "mon réseau".
2. Script de l'interface utilisateur
Ce deuxième script est en fait celui que vous avez demandé : il s'interface avec l'interface utilisateur pour cliquer sur l'icône du menu WiFi et ensuite sélectionner le réseau (s'il apparaît dans la liste). En résumé :
- + Bien qu'il s'agisse d'un script d'interface utilisateur, il ne devrait pas souffrir des mêmes faiblesses inhérentes à la plupart des script d'interface utilisateur ; on peut donc espérer qu'il sera fiable.
- + Mise en œuvre la plus rapide - les réseaux se rejoignent immédiatement
- L'utilisateur ne doit pas interagir avec le système tant que le script n'est pas sorti (la nature de tout script de l'interface utilisateur).
- Doit saisir manuellement les mots de passe s'ils ne sont pas déjà enregistrés
-
SSID insensible à la casse, correspondance floue (modifiable)
use application "System Events"
property process : a reference to application process "SystemUIServer"
property menu bar : a reference to menu bar 1 of my process
property menu bar item : a reference to (menu bar items of my menu bar ¬
where the description contains "Wi-Fi")
property menu : a reference to menu 1 of my menu bar item
property menu item : a reference to menu items of my menu
to joinNetwork given name:ssid as text
local ssid
if not (my menu bar item exists) then return false
click my menu bar item
repeat until my menu exists
delay 0.5
end repeat
set M to a reference to (my menu item where the name contains ssid)
repeat 20 times --> 10 seconds @ 0.5s delay
if M exists then exit repeat
delay 0.5
end repeat
click M
end joinNetwork
joinNetwork given name:"my network ssid"
Les scripts qui tentent de contrôler l'interface utilisateur utilisent une méthode appelée UI ou Script de l'interface graphique. Ces scripts sont populaires auprès des débutants, tout simplement parce que ce sont les scripts les plus courants sur l'internet. Je ne m'étendrai pas trop sur le sujet, si ce n'est pour vous mettre en garde contre l'utilisation de scripts qui reposent sur des clics et des frappes de touches - ils sont intrinsèquement fragiles et peu fiables, même lorsqu'ils sont bien écrits, mais la plupart des scripts d'interface utilisateur (écrits par des novices) sont terriblement mal écrits, ce qui aggrave le problème. Il existe presque toujours un meilleur moyen d'obtenir le résultat souhaité.
Cela dit, il s'agit de l'un des rares types de scripts scripts de l'interface utilisateur qui constituent peut-être une exception à mon avertissement et, à mon avis, une mise en œuvre tout à fait acceptable. En effet, il cible un aspect de l'interface utilisateur (une icône de barre de menu appartenant au système) dont l'accessibilité est pratiquement garantie, quelle que soit la fenêtre ou le bureau sur lequel porte l'attention, etc. La seule situation où le scripts de cette nature serait potentiellement cassé est si l'icône de la barre de menu n'était pas là (c'est-à-dire que l'utilisateur a spécifiquement défini une préférence pour ne pas avoir l'icône WiFi disponible) ; cependant, j'ai mis une ligne dans le scripts qui vérifie pour cela, et exécute une sortie gracieuse dans cette situation.
Ce script semble être l'implémentation la plus rapide, ce qui ne me surprend pas puisqu'il sera aussi rapide que de cliquer manuellement sur l'icône ; mais il m'impressionne car je ne vois pas beaucoup de script d'interface utilisateur qui finiraient par surpasser un script ciblé sur une application ou un service. Le réseau est rejoint presque instantanément, à condition que le mot de passe soit déjà enregistré dans votre trousseau. Parfois, le réseau que vous vous attendez à voir dans la liste du menu peut ne pas s'y trouver jusqu'à ce que le balayage en arrière-plan soit rafraîchi et que la liste soit mise à jour. C'est pourquoi j'ai prévu une période de 10 secondes pendant laquelle le script vérifie toutes les demi-secondes si l'élément de menu est apparu ; si ce n'est pas le cas, le script quitte le programme et vous devez réessayer.
L'inconvénient est que l'absence d'un mot de passe de trousseau pour un réseau vous obligera à saisir manuellement le mot de passe lorsqu'il vous sera demandé. Le mot de passe est Il est également possible de script en utilisant des techniques d'interface utilisateur, mais cela rend immédiatement le script très vulnérable aux problèmes que j'ai mentionnés et, personnellement, je ne l'utiliserais pas.
Informations sur le système : Version AppleScript : 2.7 Version du système : 10.13.6