È possibile accedere al pannello di controllo di Mac OS X quando si accede tramite SSH?

StackOverflow https://stackoverflow.com/questions/1224500

  •  22-07-2019
  •  | 
  •  

Domanda

Abbiamo il seguente frammento.

OSStatus createErr = PasteboardCreate(kPasteboardClipboard, &m_pboard);
if (createErr != noErr) {
    LOG((CLOG_DEBUG "failed to create clipboard reference: error %i" createErr));
}

Questo compila bene, tuttavia, non può essere eseguito quando chiamato da SSH. Questo perché non è disponibile un pannello di montaggio nel terminale SSH. Tuttavia, l'idea qui è quella di condividere appunti tra computer.

Quando eseguito dal terminale desktop, funziona perfettamente. Ma quando eseguito da SSH, PasteboardCreate restituisce -4960 (aka, coreFoundationUnnownErr). Suppongo che l'unico modo per ovviare a questo problema sia eseguire l'applicazione dallo stesso ambiente del pasteboard, ma è possibile?

È stato utile?

Soluzione

L'accesso diretto al pannello di controllo sembra essere un no-go. Innanzitutto, avvia non registra i processi 1 con la porta mach del server pasteboard. Dovresti prima trovare un modo per ottenere la porta mach del server pasteboard ( mach_port_names ?). Inoltre, la comunicazione diretta tra sessioni utente è proibito 2 e altre comunicazioni sono limitate. Non sono sicuro che il tuo programma disporrà dei diritti per connettersi al server pasteboard.

Ecco una prima foto di un esempio illustrativo sull'uso degli eventi Apple per ottenere & amp; imposta gli appunti come una stringa. La gestione degli errori è minima o inesistente (non sono sicuro di come mi sento su require_noerr ). Se hai intenzione di ottenere / impostare i dati degli appunti più volte durante una corsa, puoi salvare gli eventi Apple e, durante la copia negli appunti, utilizzare AECreateDesc & amp; AEPutParamDesc o (forse) AEBuildParameters . AEVTBuilder potrebbe essere utile.

NSString* paste() {
    NSString *content;

    AppleEvent paste, reply = { typeNull, 0L };
    AEBuildError buildError = { typeNull, 0L };
    AEDesc clipDesc = { typeNull, 0L };

    OSErr err;

    err = AEBuildAppleEvent(kAEJons, kAEGetClipboard, 
                            typeApplicationBundleID, "com.apple.finder", strlen("com.apple.finder"), 
                            kAutoGenerateReturnID, kAnyTransactionID,
                            &paste, &buildError,
                            ""
        );
    require_noerr(err, paste_end);
    err = AESendMessage(&paste, &reply, kAEWaitReply, kAEDefaultTimeout);
    err = AEGetParamDesc(&reply, keyDirectObject, typeUTF8Text, &clipDesc);
    require_noerr(err, pastErr_getReply);

    Size dataSize = AEGetDescDataSize(&clipDesc);
    char* clipData = malloc(dataSize);
    if (clipData) {
        err = AEGetDescData(&clipDesc, clipData, dataSize);
        if (noErr == err) {
            content = [NSString stringWithCString:clipData encoding:NSUTF8StringEncoding];
        } else {}
        free(clipData);
    }

    AEDisposeDesc(&clipDesc);
pastErr_getReply:
    AEDisposeDesc(&reply);
pasteErr_sending:
    AEDisposeDesc(&paste);
paste_end:
    return content;
}

OSStatus copy(NSString* clip) {
    AppleEvent copy, reply = { typeNull, 0L };
    AEBuildError buildError = { typeNull, 0L };

    OSErr err = AEBuildAppleEvent(kAEJons, kAESetClipboard, 
                                  typeApplicationBundleID, "com.apple.finder", strlen("com.apple.finder"), 
                                  kAutoGenerateReturnID, kAnyTransactionID,
                                  &copy, &buildError,
                                  "'----':utf8(@)",
                                  AEPARAMSTR([clip UTF8String])
                                  /*
                                    "'----':obj {form: enum(prop), want: type(@), seld: type(@), from: null()}"
                                    "data:utf8(@)",
                                    AEPARAM(typeUTF8Text),
                                    AEPARAM(pClipboard),
                                    AEPARAMSTR([clip UTF8String])
                                  */
        );
    if (aeBuildSyntaxNoErr != buildError.fError) {
        return err;
    }
    AESendMessage(&copy, &reply, kAENoReply, kAEDefaultTimeout);
    AEDisposeDesc(&reply);
    AEDisposeDesc(&copy);
    return noErr;
}

Sto lasciando l'approccio Core Foundation sopra, ma probabilmente vorrai usare NSAppleEventDescriptor per estrarre il contenuto degli appunti dalla risposta Apple Event.

    err = AESendMessage(&paste, &reply, kAEWaitReply, kAEDefaultTimeout);
require_noerr(err, pasteErr_sending);
    // nsReply takes ownership of reply
    NSAppleEventDescriptor *nsReply = [[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&reply];
    content = [[nsReply descriptorAtIndex:1] stringValue];
    [nsReply release];

pasteErr_sending:
    AEDisposeDesc(&paste);
paste_end:
    return content;
}

Un NSAppleEventDescriptor è anche più facile da esaminare in un debugger rispetto a un AEDesc . Per esaminare le risposte, puoi anche impostare la variabile di ambiente AEDebugReceives quando usi osascript o Script Editor.app:

AEDebugReceives=1 osascript -e 'tell application "Finder" to get the clipboard'

References:

  1. " Configurazione sessioni utente "
  2. " Comunicazione attraverso sessioni di accesso "
  3. Mach Kernel Interface , in particolare:
  4. CFMessagePort Reference ( mach port wrapper):

Altri suggerimenti

Ho provato a farlo in AppleScript e ha funzionato (anche se invocato tramite SSH). La mia sceneggiatura è la seguente:

#!/usr/bin/osascript

on run
    tell application "Finder"
        display dialog (get the clipboard)
    end tell
end run

Questa sicuramente non è una soluzione ideale, ma forse se hai capito come funziona AppleScript, ti aiuterebbe a implementarla da solo.

Puoi accedere al pannello di controllo con PasteboardCreate tramite SSH su SnowLeopard ma non su Leopard o Tiger.

Probabilmente non vuoi usare pbcopy e pbpaste per una sincronizzazione completa di pasteboard poiché si occupano solo di testo semplice, RTF ed EPS. Se, ad esempio, copi un'immagine e poi provi a scriverla con pbpaste, non otterrai alcun output.

Supponendo che tu abbia un'app in esecuzione nella sessione dell'utente su entrambi i computer, puoi serializzare i dati del pannello di controllo su un file, trasferirlo su SSH, leggerlo dall'app sul lato remoto e quindi inserire i dati del pannello di controllo il pannello di controllo remoto. Tuttavia, ottenere correttamente la serializzazione del pasteboard può essere complicato e non sono sicuro di quanto siano portatili i dati del pasteboard tra sistemi operativi e architetture.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top