2 votes

Pourquoi networksetup est-il si lent par rapport à la modification manuelle des réseaux Wi-Fi ?

Si je cours networksetup -setairportnetwork en0 myssid

il faut compter entre 10 et 15 secondes.

Si je clique manuellement sur l'icône Wi-Fi dans la barre de notification et que je sélectionne myssid, c'est instantané.

Sinon, j'aimerais bien pouvoir faire un applescript qui clique manuellement pour changer de réseau Wi-Fi, mais je ne trouve pas de bon exemple, tout le monde dit juste "utiliser networksetup".

Réponse : @CJK La solution proposée par M. K. fonctionne parfaitement, j'utilise son deuxième script qui effectue le clic manuel. Le premier fonctionne dans la plupart des cas, sauf lorsque j'essaie de me connecter à un réseau d'entreprise qui utilise un certificat. Pour une raison quelconque, la connexion de cette manière ne fonctionne pas dans ce cas. Mais dans tous les autres cas, les deux script fonctionnent parfaitement.

3voto

OnePablo Points 1

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

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X