wilbert wrote:I changed some thing on your code.
It doesn't crash but doesn't seem to do anything either  
 
Code: Select all
appFileName$ = StringField(ProgramFilename(),1,".app")+".app"
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)
  CFNumberCreate(allocator, type, *value)
  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)
  CFDictionaryGetTypeID()
  CFDictionaryGetValue(CFDictionaryRef.L, *KeyToFind)
  CFDictionaryCreateMutable(l1,l2,l3,l4)
  CFDictionaryAddValue(l1,l2,l3)
  CFArrayCreateMutableCopy(l1,l2,l3)
  CFArrayRemoveValueAtIndex(ArrayRef.l,Index.l)
  CFArrayAppendValue(l1,l2)
  CFRelease(obj.l)
  
EndImport
Procedure AddLoginItem(AppPath$)
  
  Rtn = #False
  ArrayRef = CFPreferencesCopyAppValue(CFSTR("AutoLaunchedApplicationDictionary"), CFSTR("loginwindow"))
  
  If ArrayRef And CFGetTypeID(ArrayRef) = CFArrayGetTypeID()
    
    newArrayRef = CFArrayCreateMutableCopy(#Null, 0, ArrayRef)
    CFRelease(ArrayRef)
    
    If newArrayRef
      
      Dim keys.i(1)
      Dim values.i(1)
      BoolFalse.l = #False
      keys(0) = CFSTR("Path")
      keys(1) = CFSTR("Hide")
      values(0) = CFStringCreateWithCString(#Null, AppPath$, 0)
      values(1) = CFNumberCreate(#Null, 3, @BoolFalse)
      newDictRef = CFDictionaryCreate(#Null, @keys(), @values(), 2, #Null, #Null)
      If newDictRef
        CFArrayAppendValue(newArrayRef, newDictRef)
        CFPreferencesSetAppValue(CFSTR("AutoLaunchedApplicationDictionary"), newArrayRef, CFSTR("loginwindow"))
        CFPreferencesAppSynchronize(CFSTR("loginwindow"))
        CFRelease(newDictRef)
        CFRelease(newArrayRef)
        Rtn = #True
      EndIf 
      CFRelease(values(1))
      CFRelease(values(0))
      
    EndIf   
  EndIf
  
  ProcedureReturn Rtn 
  
EndProcedure
Debug AddLoginItem(appFileName$)
 
Code: Select all
Global plist$ = "loginwindow"
Global pkey$ = "AutoLaunchedApplicationDictionary"
appFileName$ = StringField(ProgramFilename(),1,".app")+".app"
ImportC "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation"
  CFSTR(cStr.p-ascii) As "___CFStringMakeConstantString"
  CFDictionaryCreate(allocator, *keys, *values, numValues, *keyCallBacks, *valueCallBacks)
  CFNumberCreate(allocator, type, *value)
  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)
  CFDictionaryGetTypeID()
  CFDictionaryGetValue(CFDictionaryRef.L, *KeyToFind)
  ;CFDictionaryCreateMutable(l1,l2,l3,l4)
  CFDictionaryAddValue(l1,l2,l3)
  CFArrayCreateMutableCopy(l1,l2,l3)
  CFArrayRemoveValueAtIndex(ArrayRef.l,Index.l)
  CFArrayAppendValue(l1,l2)
  CFRelease(obj.l)
  CFBooleanGetValue(l1)
EndImport
Procedure.S ConvertCFStringIntoString(CFStringRef.l)
  Protected String.s = Space(256)
  CFStringGetCString(CFStringRef, @String, Len(String), 0)
  ProcedureReturn Trim(String)
EndProcedure
Procedure CheckLoginItem(AppPath$)
  Rtn.l = #False
  ArrayRef = CFPreferencesCopyAppValue(CFSTR(pkey$),CFSTR(plist$))
  If ArrayRef
    If 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)
            CFRelease(KeyRef)
            If StringRef
              itemFileName$ = ConvertCFStringIntoString(StringRef)
              CFRelease(StringRef) 
              Debug Str(i) + ": " + itemFileName$
              If itemFileName$ = AppPath$
                Rtn = #True
                i = ItemCount
              EndIf  
            EndIf
          EndIf
        Next i 
      EndIf   
    EndIf
    CFRelease(ArrayRef)
  EndIf
  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
            itemFileName$ = ConvertCFStringIntoString(StringRef)
            CFRelease(StringRef)
            Debug Str(i) + ": " + itemFileName$
            If itemFileName$ = AppPath$
              newArrayRef = CFArrayCreateMutableCopy(#Null, 0, 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
    CFRelease(ArrayRef)
  EndIf
  ProcedureReturn Rtn
EndProcedure
Procedure AddLoginItem(AppPath$)
  Rtn = #False
  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)
      BoolFalse.l = #False
      keys(0) = CFSTR("Path")
      keys(1) = CFSTR("Hide")
      values(0) = CFSTR(AppPath$)
      values(1) = CFNumberCreate(#Null, 3, @BoolFalse)
      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(1))
      CFRelease(values(0))
    EndIf
  EndIf
  ProcedureReturn Rtn
EndProcedure
Debug AddLoginItem(appFileName$)
Debug CheckLoginItem(appFileName$)
;Debug RemoveLoginItem(appFileName$)
thanks wilbert, you're my hero.
AddLoginItem & CheckLoginItem are working now, but RemoveLoginItem still with error of "invalid memory access".
and what's more, as the document says loginwindow.plist format must be:
Code: Select all
		<dict>
			<key>Hide</key>
			<false/>
			<key>Path</key>
			<string>/tmp/PureBasic1.app</string>
		</dict>
but now it's:
Code: Select all
		<dict>
			<key>Hide</key>
			<integer>0</integer>
			<key>Path</key>
			<string>/tmp/PureBasic1.app</string>
		</dict>
i'm confused... it's hard for me...just post all the code for some one can fix it. 
