2009-10-01 16 views
5

Pracuję nad narzędziem do automatycznego montowania woluminów sieciowych na podstawie sieci bezprzewodowej, do której jest podłączony użytkownik. Montaż głośność jest proste:Określić, czy udział sieciowy istnieje przed montażem

NSURL *volumeURL = /* The URL to the network volume */ 

// Attempt to mount the volume 
FSVolumeRefNum volumeRefNum; 
OSStatus error = FSMountServerVolumeSync((CFURLRef)volumeURL, NULL, NULL, NULL, &volumeRefNum, 0L); 

Jednakże, jeśli nie ma akcji w volumeURL sieć (jeśli ktoś wyłączone lub usunięte z twardego dysku sieciowego, na przykład), Finder wyskakuje komunikat wyjaśniający ten fakt. Moim celem jest to, aby tak się nie stało - chciałbym spróbować zamontować wolumin, ale w razie awarii nie udało się go wykonać.

Czy ktoś ma jakieś wskazówki, jak to zrobić? Idealnie byłoby znaleźć sposób sprawdzenia, czy udział istnieje przed próbą jego zamontowania (aby uniknąć niepotrzebnej pracy). Jeśli to nie jest możliwe, działałby również sposób, aby powiedzieć Finderowi, by nie wyświetlał swojego komunikatu o błędzie.

Odpowiedz

6

Ta odpowiedź korzysta z prywatnych frameworków. Jak wskazuje naixn w komentarzach, oznacza to, że może się on równomiernie złamać w przypadku wydania kropki.

Nie można tego zrobić za pomocą wyłącznie publicznego interfejsu API (który można znaleźć po kilku godzinach wyszukiwania/dezasemblacji).

Ten kod będzie mieć dostęp do adresu URL i nie będzie wyświetlany żaden element interfejsu użytkownika przekazywany lub nieudany. Obejmuje to nie tylko błędy, ale także okna dialogowe uwierzytelniania, okna dialogowe wyboru itp.

Ponadto, to nie Finder wyświetla te komunikaty, ale NetAuthApp z CoreServices. Wywoływana tutaj funkcja (netfs_MountURLWithAuthenticationSync) jest wywoływana bezpośrednio z funkcji w pytaniu (FSMountServerVolumeSync). Wywołanie go na tym poziomie pozwala nam zdać flagę .

Po sukcesie, rc ma wartość 0, a punkty montowania zawierają listę NSStrings z zamontowanych katalogów.

// 
// compile with: 
// 
// gcc -o test test.m -framework NetFS -framework Foundation 
include <inttypes.h> 
#include <Foundation/Foundation.h> 

// Calls to FSMountServerVolumeSync result in kSoftMount being set 
// kSuppressAllUI was found to exist here: 
// http://www.opensource.apple.com/source/autofs/autofs-109.8/mount_url/mount_url.c 
// its value was found by trial and error 
const uint32_t kSoftMount  = 0x10000; 
const uint32_t kSuppressAllUI = 0x00100; 

int main(int argc, char** argv) 
{ 
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 

    NSURL *volumeURL = [NSURL URLWithString:@"afp://server/path"]; 
    NSArray* mountpoints = nil; 

    const uint32_t flags = kSuppressAllUI | kSoftMount; 

    const int rc = netfs_MountURLWithAuthenticationSync((CFURLRef)volumeURL, NULL, NULL, 
      NULL, flags, (CFArrayRef)&mountpoints); 

    NSLog(@"mountpoints: %@; status = 0x%x", mountpoints, rc); 

    [pool release]; 
} 
+1

Należy pamiętać, że kSoftMount && kSuppressAllUI wraz z netfs_MountURLWithAuthenticationSync, są z PrivateFrameworks. Oznacza to, że może działać w twoim bieżącym systemie, ale może zostać uszkodzony w przyszłych wydaniach (nawet kropkowych). –

+0

Absolutnie poprawne. Opublikowalem to tylko dlatego, że nie można tego zrobić z bieżącym publicznym interfejsem API. – nall

+0

Witam wszystkich, Utknąłem z tym samym problemem jeszcze raz !!! Czy dysponujemy czystszym rozwiązaniem dostępnym dla tego problemu? Próbowałem używać tego interfejsu API, ale dostaję błąd, że "netfs_MountURLWithAuthenticationSync" jest nieznanym identyfikatorem ... – PRIME

Powiązane problemy