2012-01-17 48 views
3

我已經知道如何使用Objective-C中的Mac OSX輔助功能API來重新定位另一個正在運行的應用程序的窗口,而無需使用任何類型的腳本橋接器。使用Accessibility API關閉另一個應用程序的所有窗口

現在,我想使用這個相同的Accessibility API(同樣,沒有任何腳本橋)來關閉另一個正在運行的應用程序的所有打開的窗口。

,我想在Objective-C編寫應該做同樣的事情,因爲這AppleScript的代碼代碼:

tell application "TheApplication" 
close every window 
end tell 

我猜想,這是可能的,因爲它的內AppleScript的允許。

+0

PS:當我說 「沒有任何腳本橋」,我的意思是沒有NSApplescript調用。我使用AXUIElementCopyAttributeValue和相關調用來執行基於非applescript的窗口重新定位,但我無法弄清楚如何使用AXUI API來執行窗口刪除。如果這個問題的目的是爲了查看是否可以在沒有NSApplescript或任何其他類似的Applescript發送調用的情況下完成此操作。謝謝。 – HippoMan 2012-01-17 19:54:01

回答

5

這裏是我的解決方案...

+(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; 
    } 
} 
+1

感謝您分享您的工作! – 2012-01-18 03:03:09

+0

按下按鈕NSAccessibilityCancelButtonAttribute也可以在某些情況下非常有用,如果關閉沒有定義。同時發送動作kAXCancelAction有時可能會有所幫助。 – 2014-01-03 15:21:21

2

有一個Cocoa類,NSApplescript,它可以讓你從你的ObjC代碼中編譯和運行Applescript。你沒有真正說過你爲什麼不想使用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]; 

憂後意識形態的純潔性或性能。

+0

非常感謝,但我知道我可以這樣做。當我說我不想使用腳本橋時,我的意思是我正在尋找一種非NSApplescript方法來實現這一點。我進行窗口重定位的方式涉及AXUIElementCopyAttributeValue調用,但我無法弄清楚如何使用此AXUI API執行窗口刪除。有任何想法嗎?謝謝。 – HippoMan 2012-01-17 19:49:17

+0

我明白你的意思,但是你沒有提供任何不想使用AS的理由,而且我正在質疑這個願望。 – 2012-01-17 19:53:41

+0

我的願望是編寫一個非Applescript相關的框架來完成這些類型的任務。這部分是作爲一種學習經驗。我已經構建了一個包含用於重新定位窗口的很好例程的包,僅使用AXUI API,並且我想添加到我的這個包來完成窗口刪除。 – HippoMan 2012-01-17 19:57:47

相關問題