[OSX LION] Add/Check/Remove login item using CFPreferences

Mac OSX specific forum
wy328
User
User
Posts: 18
Joined: Sun Jan 15, 2012 3:08 am

[OSX LION] Add/Check/Remove login item using CFPreferences

Post by wy328 »

i'm new to purbasic and happy to play with it.
but using api calls is not easy in pb under lion,some times it just not work as it should be.... :|
after a hard work ( :shock: ),i managed to make these code working.
very much thanks to wilbert! :D
feel free to use these,and tell me if you made it better. :mrgreen:
#plist = "loginwindow"
#pkey = "AutoLaunchedApplicationDictionary"

appFileName$ = StringField(ProgramFilename(),1,".app")+".app"


; *** code to get kCFBooleanTrue and kCFBooleanFalse ***

Global.l kCFBooleanTrue, kCFBooleanFalse
!mov eax, dword [kCFBooleanTruePtr]
!mov edx, dword [kCFBooleanFalsePtr]
!mov eax, [eax]
!mov edx, [edx]
!mov [v_kCFBooleanTrue], eax
!mov [v_kCFBooleanFalse], edx
DataSection
!extern _kCFBooleanTrue
!extern _kCFBooleanFalse
!kCFBooleanTruePtr: dd _kCFBooleanTrue
!kCFBooleanFalsePtr: dd _kCFBooleanFalse
EndDataSection

; *** end of code to get kCFBooleanTrue and kCFBooleanFalse ***


ImportC "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation"

CFSTR(cStr.p-ascii) As "___CFStringMakeConstantString"
CFStringCreateWithCString(allocator, cStr.p-ascii, encoding)
CFDictionaryCreate(allocator, *keys, *values, numValues, *keyCallBacks, *valueCallBacks)
CFPreferencesSetAppValue(l1,l2,l3)
CFPreferencesCopyAppValue(l1,l2)
CFStringGetCStringPtr(l1,l2)
CFStringGetCString(CFStringRef.L, *StringBuffer, BufferSize.L, CFStringEncoding.L)
CFStringGetTypeID()
CFPreferencesAppSynchronize(l1)
CFGetTypeID(l1)
CFArrayGetTypeID()
CFArrayGetCount(CFArrayRef.l)
CFArrayGetValueAtIndex(CFArrayRef.L, Index.L)
CFDictionaryGetValue(CFDictionaryRef.L, *KeyToFind)
CFDictionaryAddValue(l1,l2,l3)
CFArrayCreateMutableCopy(l1,l2,l3)
CFArrayRemoveValueAtIndex(ArrayRef.l,Index.l)
CFArrayAppendValue(l1,l2)
CFRelease(obj.l)
EndImport

Macro ConvertCFStringIntoString(CFStringRef,CString)
Buffer.s = Space(256)
CFStringGetCString(CFStringRef, @Buffer, Len(Buffer), 0)
CString = Trim(Buffer)
EndMacro

Procedure CheckLoginItem(AppPath$)
Rtn.l = #False
ArrayRef = CFPreferencesCopyAppValue(CFSTR(#pkey),CFSTR(#plist))
If ArrayRef And CFGetTypeID(ArrayRef) = CFArrayGetTypeID()
ItemCount = CFArrayGetCount(ArrayRef)
If ItemCount > 1
For i = 0 To ItemCount - 1
DictionaryRef = CFArrayGetValueAtIndex(ArrayRef, i)
If DictionaryRef
KeyRef = CFSTR("Path")
StringRef = CFDictionaryGetValue(DictionaryRef, KeyRef)
If StringRef
ConvertCFStringIntoString(StringRef,itemFileName$)
;Debug Str(i) + ": " + itemFileName$
If itemFileName$ = AppPath$
Rtn = #True
i = ItemCount
EndIf
EndIf
EndIf
Next i
EndIf
CFRelease(ArrayRef)
EndIf
Debug "Check Item:" + Str(rtn)
ProcedureReturn Rtn
EndProcedure

Procedure RemoveLoginItem(AppPath$)
Rtn.l = #False
ArrayRef = CFPreferencesCopyAppValue(CFSTR(#pkey),CFSTR(#plist))
If ArrayRef And CFGetTypeID(ArrayRef) = CFArrayGetTypeID()
ItemCount = CFArrayGetCount(ArrayRef)
;Debug "array: " + Str(CFArrayGetCount(ArrayRef))
If ItemCount > 1
For i = 0 To ItemCount - 1
DictionaryRef = CFArrayGetValueAtIndex(ArrayRef, i)
If DictionaryRef
KeyRef = CFSTR("Path")
StringRef = CFDictionaryGetValue(DictionaryRef, KeyRef)
CFRelease(KeyRef)
If StringRef
ConvertCFStringIntoString(StringRef,itemFileName$)
;Debug Str(i) + ": " + itemFileName$
If itemFileName$ = AppPath$
newArrayRef = CFArrayCreateMutableCopy(#Null, 0, ArrayRef)
CFRelease(ArrayRef)
If newArrayRef
CFArrayRemoveValueAtIndex(newArrayRef,i)
;Debug "new array: " + Str(CFArrayGetCount(newArrayRef))
CFPreferencesSetAppValue(CFSTR(#pkey), newArrayRef, CFSTR(#plist))
CFPreferencesAppSynchronize(CFSTR(#plist))
CFRelease(newArrayRef)
Rtn = #True
i = ItemCount
EndIf
EndIf
EndIf
EndIf
Next i
EndIf
EndIf
Debug "Remove Item:" + Str(rtn)
ProcedureReturn Rtn
EndProcedure

Procedure AddLoginItem(AppPath$)
Rtn = #False
If Not CheckLoginItem(AppPath$)
ArrayRef = CFPreferencesCopyAppValue(CFSTR(#pkey), CFSTR(#plist))
If ArrayRef And CFGetTypeID(ArrayRef) = CFArrayGetTypeID()
newArrayRef = CFArrayCreateMutableCopy(#Null, 0, ArrayRef)
CFRelease(ArrayRef)
If newArrayRef
Dim keys.i(1)
Dim values.i(1)
keys(0) = CFSTR("Path")
keys(1) = CFSTR("Hide")
values(0) = CFStringCreateWithCString(#Null, AppPath$, 0)
values(1) = kCFBooleanFalse
newDictRef = CFDictionaryCreate(#Null, @keys(), @values(), 2, #Null, #Null)
If newDictRef
CFArrayAppendValue(newArrayRef, newDictRef)
CFPreferencesSetAppValue(CFSTR(#pkey), newArrayRef, CFSTR(#plist))
CFPreferencesAppSynchronize(CFSTR(#plist))
CFRelease(newDictRef)
CFRelease(newArrayRef)
Rtn = #True
EndIf
CFRelease(values(0))
EndIf
EndIf
EndIf
Debug "Add Item:" + Str(rtn)
ProcedureReturn Rtn
EndProcedure


Debug "App Path:" + appFileName$
AddLoginItem(appFileName$)
;CheckLoginItem(appFileName$)
RemoveLoginItem(appFileName$)
; IDE Options = PureBasic 4.60 (MacOS X - x86)