Закройте все окна другого приложения с помощью API доступа - PullRequest
3 голосов
/ 17 января 2012

Я уже знаю, как использовать API доступности Mac OSX в Objective-C для изменения положения окон другого работающего приложения, без использования какого-либо скриптового моста.

Теперь я хочу использовать этот же API доступа (опять же, без какого-либо скриптового моста), чтобы закрыть все открытые окна другого работающего приложения.

Код, который я хочу написать в Objective-C, должен делать то же самое, что и код AppleScript:

tell application "TheApplication"
close every window
end tell

Я бы предположил, что это возможно, потому что это разрешено в AppleScript.

Ответы [ 2 ]

5 голосов
/ 18 января 2012

Вот мое решение ...

+(void)closeWindowsOfApp:(NSString*)appName {

    boolean_t result = false;

    if (appName == nil) {
        return;
    }

    ProcessSerialNumber psn;
    psn.highLongOfPSN = 0;
    psn.lowLongOfPSN  = kNoProcess;

    while (GetNextProcess(&psn) == noErr) {

        pid_t pid = 0;

        if (GetProcessPID(&psn, &pid) != noErr) {
            continue;
        }

        AXUIElementRef elementRef = AXUIElementCreateApplication(pid);
        NSString* title = nil;
        AXUIElementCopyAttributeValue(elementRef, kAXTitleAttribute, (CFTypeRef *)&title);
        if (title == nil) {
            continue;
        }
        if ([title compare:appName] != NSOrderedSame) {
            CFRelease(title);
            continue;      
        }
        CFRelease(title);

        CFArrayRef windowArray = nil;
        AXUIElementCopyAttributeValue(elementRef, kAXWindowsAttribute, (CFTypeRef*)&windowArray);
        if (windowArray == nil) {
            CFRelease(elementRef);
            continue;
        }
        CFRelease(elementRef);

        CFIndex nItems = CFArrayGetCount(windowArray);
        if (nItems < 1) {
            CFRelease(windowArray);
            continue;
        }

        for (int i = 0; i < nItems; i++) {
            AXUIElementRef itemRef = (AXUIElementRef) CFArrayGetValueAtIndex(windowArray, i);
            AXUIElementRef buttonRef = nil;
            AXUIElementCopyAttributeValue(itemRef, kAXCloseButtonAttribute, (CFTypeRef*)&buttonRef);
            AXUIElementPerformAction(buttonRef, kAXPressAction);
            CFRelease(buttonRef);
        }

        CFRelease(windowArray);
        break;
    }
}
2 голосов
/ 17 января 2012

Существует класс Cocoa, NSApplescript, который позволяет вам компилировать и запускать Applescript из кода ObjC.Вы действительно не сказали, почему вы не хотите использовать AS.Поскольку у вас уже есть скрипт, который делает то, что вы хотите, вы можете заставить свою программу работать прямо сейчас и просто использовать ее:

NSApplescript * as = [[NSApplescript alloc] initWithSource:@"tell application \"TheApplication\"\nclose every window\nend tell"];
NSDictionary * errInfo;
NSAppleEventDescriptor * res = [as executeAndReturnError:&err];
if( !res ){
    // An error occurred. Inspect errInfo and perform necessary actions
}

[as release];

Беспокойтесь об идеологической чистоте или производительности позже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...