Remove an item from side bar using Applescript on Mac OS - objective-c

Does anyone know how can I remove an item from favourites list on finder's sidebar using applescript, If it is not possible from applescript can we do something with shell script or terminal command on Mac OS?
Here is what I did to add it via applescript:
I opened the folder which I wanted to add to the sidebar and used a shortcut (Command+Control+t) to add it to favourites menu of finder's sidebar.
Please suggest if there is any other way to do this.
Thanks
This is how we can do it using objective-c:
LSSharedFileListRef sflRef = LSSharedFileListCreate(NULL, kLSSharedFileListFavoriteItems, NULL);
AuthorizationRef auth = NULL;
NSString *itemName = #"";
AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &auth);
LSSharedFileListSetAuthorization(sflRef, auth);
UInt32 seed;
if(sflRef){
NSArray *list = (__bridge NSArray *)LSSharedFileListCopySnapshot(sflRef, &seed);
LSSharedFileListItemRef sflItemRef = NULL;
for(NSObject *object in list) {
sflItemRef = (__bridge LSSharedFileListItemRef)object;
CFStringRef nameRef = LSSharedFileListItemCopyDisplayName(sflItemRef);
itemName = (__bridge NSString*)nameRef;
NSLog(#"%#", itemName);
if ([itemName isEqualToString:#"YourItem"]) {
LSSharedFileListItemRemove(sflRef, sflItemRef);
break;
}
}
}
CFRelease(sflRef);

Related

How to get list of all start up/login applications on mac?

I want to get a list/array of all the application that are launch at the startup Mac using objective c.
Thanks in advance!!
here is the code to get all the applicaiton list from startup
// Get the LoginItems list.
LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
if (loginItemsRef == nil) return nil;
// Iterate over the LoginItems.
NSArray *loginItems = (__bridge NSArray *)LSSharedFileListCopySnapshot(loginItemsRef, nil);
for (id item in loginItems) {
// do what you want
}

Retrieving keys from a custom system-wide keychain in Mac OS X 10.7+

I am working on an app for OSX Lion and onwards. The app has a root daemon process. I have created a system-wide keychain using "SecKeychainCreate" in /Library/Keychains which is accessible only by the daemon and wish to store generic keys in that keychain. Can anyone help me with retrieving generic keys from this keychain programmatically ? To add a key to the keychain, I used the "SecKeychainItemCreateFromContent" function as it accepts a SecKeychainRef parameter and passed kSecPublicKeyItemClass as the first parameter. Here is my code :
char *itemLabel = "Generic public key";
//Setting up the attribute vector (each attribute consists of {tag, length, pointer}):
SecKeychainAttribute attrs[] = {kSecLabelItemAttr, strlen(itemLabel), itemLabel};
SecKeychainAttributeList attributes = { sizeof(attrs)/sizeof(attrs[0]), attrs };
//pubKey is the key (NSData) that I want to store, while tempKeyChain is my keychain
status = SecKeychainItemCreateFromContent(kSecPublicKeyItemClass, &attributes, [pubKey length],(__bridge const void *)pubKey, tempKeyChain, NULL, NULL);
if (status != noErr)
{
NSString *error = (__bridge NSString *)SecCopyErrorMessageString(status, NULL);
NSLog(#"Error in adding item to keychain : %#",error);
return errSecUnimplemented;
}
Now, to retrieve the key, there are two options - "SecKeychainSearchCreateFromAttributes" which is deprecated in OS X 10.7 and so is useless, or "SecItemCopyMatching". The former accepts a SecKeychainRef parameter while the latter does not. So, I manually set my search list using "SecKeychainSetSearchList" to include tempKeyChain, and then used "SecItemCopyMatching". Here is the code for that :
OSStatus status;
SecKeychainRef defaultKeychain = nil;
SecKeychainCopyDefault(&defaultKeychain);
NSArray *searchList = [NSArray arrayWithObjects:(__bridge id)defaultKeychain,tempKeyChain, nil];
OSStatus result = SecKeychainSetSearchList((__bridge CFArrayRef)searchList);
if (result != noErr)
{
NSString *error = (__bridge NSString *)SecCopyErrorMessageString(result, NULL);
NSLog(#"Error : %#",error);
return errSecUnimplemented;
}
NSMutableDictionary *query = [[NSMutableDictionary alloc] init];
[query setObject:kSecClassKey forKey:(id)kSecClass];
[query setObject:#"Generic public key" forKey:kSecAttrLabel];
CFTypeRef items;
status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &items);
return status;
This code always gives a status of "Item not found", even though my keychain is added to the search list alongwith the default search list.
I would greatly appreciate any pointers on why this might be happening, or any other better ways to store and retrieve keys from a custom keychain.
P.S - I do not want to store passwords, only keys (public and private). Could anyone guide me to some code or present a small code snippet explaining the same ? Thanks.

How to identify window under mouse with Objective-C?

I have the following code:
id eventHandler = [NSEvent addGlobalMonitorForEventsMatchingMask:NSMouseMovedMask handler:^(NSEvent * event) {
CGWindowID windowID = (CGWindowID)[event windowNumber];
CFArrayRef a = CFArrayCreate(NULL, (void *)&windowID, 1, NULL);
NSArray *windowInfos = (__bridge NSArray *)CGWindowListCreateDescriptionFromArray(a);
CFRelease(a);
if ([windowInfos count] > 0) {
NSDictionary *windowInfo = [windowInfos objectAtIndex:0];
NSLog(#"Name: %#", [windowInfo objectForKey:(NSString *)kCGWindowName]);
NSLog(#"Owner: %#", [windowInfo objectForKey:(NSString *)kCGWindowOwnerName]);
//etc.
}
}];
Which does a pretty good job at identifying windows under the cursor. However, in order to identify them reliably you must click on the window. Some windows will trigger a change such as terminal and xcode, but hovering over say the desktop does not trigger that Finder is under the cursor. However if you click on the desktop then it is correctly identified. Any ideas what I might be missing?

Fixing "Use of undeclared identifier 'NSPreferencePanesDirectory'"

My application uses the following code:
#if MAC_OS_X_VERSION_10_5 < MAC_OS_X_VERSION_MAX_ALLOWED
NSArray *globalPreferencePanes =
NSSearchPathForDirectoriesInDomains(NSPreferencePanesDirectory,
NSAllDomainsMask, YES);
#else
NSArray *globalPreferencePanes =
[NSArray arrayWithObjects:#"/Library/PreferencePanes",
[#"~/Library/PreferencePanes" stringByExpandingTildeInPath], nil];
#endif
return globalPreferencePanes;
The project under which I'm compiling this is aimed at the 10.5 Mac OSX SDK, where NSPreferencePanesDirectory does not exist (it only exists in 10.6+). Because of this, I have the #if and #else in order to check what version of Mac OSX we're running under, so I know whether I should use the NSPreferencePanesDirectory or just manually give the location of the preference pane directories.
What should I change in order to stop getting this "use of undeclared identifier" error?
Thanks.
#if is evaluated at compile time, not run time. What you probably want to do is use the current SDK (10.7), and do something like this:
NSArray *globalPreferencePanes;
if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_6)
globalPreferencePanes = NSSearchPathForDirectoriesInDomains(NSPreferencePanesDirectory, NSAllDomainsMask, YES);
else
globalPreferencePanes = [NSArray arrayWithObjects:#"/Library/PreferencePanes", [#"~/Library/PreferencePanes" stringByExpandingTildeInPath], nil];
return globalPreferencePanes;
Making sure to set your target OS version to 10.5 so the symbol is weak linked. Otherwise, you could drop down and use CoreServices' FSFindFolder():
NSMutableArray *globalPreferencePanes = [NSMutableArray array];
FSRef foundRef;
OSErr err = FSFindFolder(kLocalDomain, kPreferencePanesFolderType, false, &foundRef);
if (err != noErr) {
CFURLRef url = CFURLCreateFromFSRef(NULL, &fsRef);
CFStringRef path = CFURLCopyPath(url);
[globalPreferencePanes addObject:(id)path];
CFRelease(path);
CFRelease(url);
}
OSErr err = FSFindFolder(kUserDomain, kPreferencePanesFolderType, false, &foundRef);
if (err != noErr) {
CFURLRef url = CFURLCreateFromFSRef(NULL, &fsRef);
CFStringRef path = CFURLCopyPath(url);
[globalPreferencePanes addObject:(id)path];
CFRelease(path);
CFRelease(url);
}
return globalPreferencePanes;
(Not tested)
If you are using 10.5.x you will still get an error since "NSPreferencePanesDirectory" is not a known symbol. I solved this issue for a friend and changed the FindPrefsDir function code in osxsupport.m to:
char *FindPrefsDir(void)
{
char *resstr = NULL;
NSArray *globalPreferencePanes;
globalPreferencePanes = [NSArray arrayWithObjects:#"/Library/PreferencePanes", [#"~/Library/PreferencePanes" stringByExpandingTildeInPath], nil];
if ([globalPreferencePanes count] > 0)
{
resstr = StringToChar([globalPreferencePanes objectAtIndex:0]) ;
}
return resstr;
}
Thanks to Wevah for his code suggestion, but it didn't directly work for me. So I changed it a little bit and my friend who is still on 10.5.x could perfectly build it after that.

How to get the file item right-clicked in Finder on OSX

I'm writing a plugin via mach_inject to add an item to Finder context menu. I have successfully add it by hooking NSMenu. But now i need to get the item that is right-clicked.
Someone said we could use the following code, but it can only get the selected items instead of right-clicked item (They are different!!!! In Finder, if you select one item and right-clicked another item, the selected one won't change). Anyone knows how to get right-click item in Finder? Thanks!
SBElementArray * selection = [[finder selection] get];
NSArray * items = [selection arrayByApplyingSelector:#selector(URL)];
for (NSString * item in items) {
NSURL * url = [NSURL URLWithString:item];
NSLog(#"selected item url: %#", url);
}
Before get the selected files, you should prepare some help code
struct TFENode {
struct OpaqueNodeRef *fNodeRef;
};
struct TFENodeVector {
struct TFENode *_begin;
struct TFENode *_end;
struct TFENode *_end_cap;
};
- (NSArray *)arrayForNodeVector:(const struct TFENodeVector *)vector
{
NSInteger capacity = vector->_end - vector->_begin;
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:capacity];
struct TFENode *node;
for (node = vector->_begin; node < vector->_end; ++node) {
[array addObject: [self pathForNode:node]];
}
return array;
}
You can get files like this
// Snow Leopard & Lion
// gNodeHelper is where you put above code
// override_handleContextMenuCommon: is your override function
+ (void)override_handleContextMenuCommon:(unsigned int)context
nodes:(const struct TFENodeVector *)nodes
event:(id)event
view:(id)view
windowController:(id)windowController
addPlugIns:(BOOL)flag
{
NSArray *paths = [gNodeHelper arrayForNodeVector:nodes];
[self override_handleContextMenuCommon:context
nodes:nodes
event:event
view:view
windowController:windowController
addPlugIns:flag];
}