使用Accessibility API关闭另一个应用的所有窗口

Hip*_*Man 3 macos cocoa accessibility window objective-c

我已经知道如何在Objective-C中使用Mac OSX Accessibility API来重新定位另一个正在运行的应用程序的窗口,而无需使用任何类型的脚本桥.

现在,我想使用相同的辅助功能API(再次,没有任何脚本桥)来关闭另一个正在运行的应用程序的所有打开的窗口.

我想在Objective-C中编写的代码应该与AppleScript代码完全相同:

tell application "TheApplication"
close every window
end tell
Run Code Online (Sandbox Code Playgroud)

我猜这是可能的,因为它在AppleScript中是允许的.

Hip*_*Man 6

这是我的解决方案......

+(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;
    }
}
Run Code Online (Sandbox Code Playgroud)