2015-08-18 24 views
18

Ich versuche, die DNS-Server auf meinem Mac (10.10.4) mit PyObjC (3.0.4) zu ändern.Ändern der DNS-Einstellungen mit PyObjC

Alles scheint zu funktionieren: Ich bekomme einen Authentifizierungsdialog aufgefordert, dass mein Programm versucht, die Netzwerkeinstellungen zu ändern, und die Durchführungs-/anwenden Befehle geben True, die sie erfolgreich waren hinweisen.

Die Systemeinstellungen werden jedoch nicht tatsächlich geändert: Sie bleiben die gleichen wie zuvor. Irgendeine Idee, warum sie nicht "haften"?

Der Code (Standalone, sollte funktionieren, wenn Sie eine aktuelle Version von PyObjC installiert haben):

#!/usr/bin/env python 

import objc 
from SystemConfiguration import * 

# Open dynamic store and get primary interface 
store = SCDynamicStoreCreate(None, 'MyApp', None, None) 
primaryif = SCDynamicStoreCopyValue(store, 'State:/Network/Global/IPv4')['PrimaryInterface'] 
if primaryif: 
    print "Using %s as primary interface" % primaryif 
else: 
    raise "Can't find primary interface" 

# Load SecurityInterface framework to provide SFAuthorization 
objc.initFrameworkWrapper(
    frameworkName  = "SecurityInterface", 
    frameworkIdentifier = "com.apple.securityinterface", 
    frameworkPath  = objc.pathForFramework("/System/Library/Frameworks/SecurityInterface.framework"), 
    globals    = globals() 
) 

# Access system preferences 
preferences = SCPreferencesCreateWithAuthorization(None, 'MyApp', None, SFAuthorization.authorization().authorizationRef()) 

# Lock preferences 
SCPreferencesLock(preferences, True) 

# Get list of network services 
networkSet = SCNetworkSetCopyCurrent(preferences) 
networkSetServices = SCNetworkSetCopyServices(networkSet) 

# Find the network service that belongs to the primary interface 
for networkService in networkSetServices: 
    interface = SCNetworkServiceGetInterface(networkService) 
    if primaryif != SCNetworkInterfaceGetBSDName(interface): 
     continue 

    # Load currently configured DNS servers 
    networkProtocol = SCNetworkServiceCopyProtocol(networkService, kSCNetworkProtocolTypeDNS) 
    DNSDict = SCNetworkProtocolGetConfiguration(networkProtocol) or {} 

    # Set new DNS servers 
    DNSDict[kSCPropNetDNSServerAddresses] = [ '192.168.23.12', '8.8.4.4' ] 
    SCNetworkProtocolSetConfiguration(networkService, DNSDict) 

    # Unlock, commit and apply preferences 
    print "UL", SCPreferencesUnlock(preferences) 
    print "CO", SCPreferencesCommitChanges(preferences) 
    print "AP", SCPreferencesApplyChanges(preferences) 

EDIT: Die meisten der oben genannten Code basiert auf this page, die auch als "berührend", schlägt die dynamischer Speicher, um die Einstellungen beizubehalten (der entsprechende Code wird am Ende auskommentiert). Es scheint jedoch nichts zu tun.

EDIT # 2: durch /usr/sbin/networksetup Auseinanderbauen Ich erhalte die Idee, dass ich eine Reihe spezifischer Rechte benötigen (system.services.systemconfiguration.network), bevor Änderungen akzeptiert werden.

+1

Haben Sie versucht, das Skript mit 'sudo' auszuführen? –

+0

@ l'L'l ja, das ändert nichts (wörtlich) :-( – robertklep

+0

Ich habe gerade versucht das Skript und ich bekomme einen Fehler, nachdem es um die Autorisierung fragt: 'DNSDict [kSCPropNetDNSServerAddresses] = ['192.168.23.12' , '8.8.4.4'] TypeError: 'NoneType' -Objekt unterstützt keine Item-Zuweisung' –

Antwort

1

Sieht so aus, als gäbe es Probleme mit PyObjC, die dazu führen, dass dies nicht funktioniert, aber Sie können möglicherweise einen Weg finden, indem Sie eine andere Lösung verwenden. Wenn ich Sie wäre und meine Situation es erlaubte, würde ich einfach die System-Kommandozeilen-Tools aufrufen, um die DNS-Server zu setzen.

Nach OSXDaily, können Sie dies mit:

networksetup -setdnsservers (Network Service) (DNS IP) 

Wenn Sie Cross-Plattform-Anforderungen haben dies als wünschenswert offensichtlich weniger ist.

+0

Danke für den Vorschlag: DI hat bereits 'networksetup' verwendet (siehe [diesen Kommentar] (http://stackoverflow.com/questions/32073573/changing-dns-settings-using-pyobjc/40538034 # comment52226266_32073573)) und suchte nach einem reinen PyObjC-Ersatz. Ich habe es nie geschafft, dass es so funktioniert, aber "networksetup" zu verwenden ist akzeptabel. – robertklep