[OSX LION] Add/Check/Remove login item using CFPreferences
Posted: Fri Jan 27, 2012 10:22 am
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 (
),i managed to make these code working.
very much thanks to wilbert!
feel free to use these,and tell me if you made it better.
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 (

very much thanks to wilbert!

feel free to use these,and tell me if you made it better.

#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)