Professional Web Applications Themes

C calls to set login item. - Mac Programming

Hi, I'm trying to figure out how to get my application to start when a user logs in. It would seem that we need to use CFPreference calls in some way. But I'm missing some important details. We need a reference to the place where the value is being stored. So we'd use something like: CFStringRef appID = CFSTR("com.apple.??????"); I've looked for something like: "com.apple.systempreferences" but it doesn't exist for me. So question 1 is: what should this string be? Then we'd need some key to set, as in: CFStringRef appKey = CFSTR("login-items"); Question 2 is: what should this string ...

  1. #1

    Default C calls to set login item.

    Hi,

    I'm trying to figure out how to get my application to start when a user
    logs in. It would seem that we need to use CFPreference calls in some
    way. But I'm missing some important details.
    We need a reference to the place where the value is being stored. So
    we'd use something like:

    CFStringRef appID = CFSTR("com.apple.??????");

    I've looked for something like: "com.apple.systempreferences" but it
    doesn't exist for me. So question 1 is: what should this string be?
    Then we'd need some key to set, as in:

    CFStringRef appKey = CFSTR("login-items");

    Question 2 is: what should this string be?
    Then we need to say what application to launch:

    CFStringRef appPath = CFSTR("/Application/MyApp.app");

    Question 3 is: should this be full path to the application or should it
    be something else?
    Once these parameters are set, I guess that it's then a matter of
    calling the following calls:

    CFPreferencesSetValue(appKey,
    appPath,
    appID,
    kCFPreferencesCurrentUser,
    kCFPreferencesAnyHost);

    CFPreferencesSynchronize(appID,
    kCFPreferencesCurrentUser,
    kCFPreferencesAnyHost);

    Are there any further pieces of advice? For example, are there tricks
    that need to be applied so that other people's login items aren't
    deleted by accident?

    Thanks,

    Andrew
    Andew Guest

  2. #2

    Default Re: C calls to set login item.

    In article <ihug.co.nz>,
    Andew <com> wrote:
     

    Contact Apple Developer Technical Support to get the Apple-approved way to
    accomplish that.

    meeroh

    --
    If this message helped you, consider buying an item
    from my wish list: <http://web.meeroh.org/wishlist>

    Miro Guest

  3. #3

    Default Re: C calls to set login item.

    In article <ihug.co.nz>,
    Andew <com> wrote:
     

    E-Mail Apple's Developer Technical support (their username on apple.com
    is "dts"). They have some "Login Items API" sample code that does what
    you want. (no, there is no real login items API)

    Cheers,
    -- M. Uli Kusterer
    http://www.zathras.de
    Uli Guest

  4. #4

    Default Re: C calls to set login item.

    On 31/01/2004, Andew wrote in message <andrew-
    ihug.co.nz>:
     

    Failing any more technically-C method of doing it, cause your C program
    to issue a shell command (any shell) and do a 'man defaults' to find out
    what command you should be issuing.

    Simon.
    --
    Posted using test version of software.
    Please tell me if anything isn't right.
    Simon Guest

  5. #5

    Default Re: C calls to set login item.

    On Tue, 3 Feb 2004, Simon Slavin wrote:
     
    >
    > Failing any more technically-C method of doing it, cause your C program
    > to issue a shell command (any shell) and do a 'man defaults' to find out
    > what command you should be issuing.[/ref]

    Of course anything you can do with defaults you can do with CFPreferences

    Fred 

    Frederick Guest

  6. #6

    Default Re: C calls to set login item.

    Uli Kusterer <de> wrote:
     
    >
    > E-Mail Apple's Developer Technical support (their username on apple.com
    > is "dts"). They have some "Login Items API" sample code that does what
    > you want. (no, there is no real login items API)[/ref]

    Thanks for the response. But I'm not registered with Apple. And since I
    don't pay them for tech support I don't really have the right to email
    them with my questions. I was hoping for a few hints - just enough for
    me to figure out how to start this.

    I'm a nobody. I write software for free and release all the source. (If
    you can be bothered: search for "Single Brain Cell Software" and you'll
    find me ... please note, a recent flood of spam appears to have broken
    the email server so you'll not be able to contact me.)

    I do things for free and without expectation of reward. Thus I need to
    do things as cheaply a possible. I can't afford to pay Apple to ask this
    sort of question. (Although I wish that I could afford it, because I
    would.) Thus I definitely can't email them on this.

    My current solution is a bit bad, but it will do. I'll just launch the
    System Preferences and give people instructions how to add my
    application to the login items. I know - it's not good, but I can do at
    least that much.

    Don't fret too much over this solution. The project is having some real
    problems and probably won't see the light of day anyway. But it's good
    having a go.

    Thanks for everything,

    Andrew

    (Some moron who write free and open software of no particular merit. :)
    Andew Guest

  7. #7

    Default Re: C calls to set login item.

    In article <ihug.co.nz>,
    Andew <com> wrote:
     

    Hey Andrew,

    A few days ago I was wondering the same thing as you, how to alter the
    login items programmatically. I dug all over the system and couldn't
    find anything. It must be stored somewhere, but wherever it is it's not
    plain text.

    I also don't have the resources to email DTS..i'm going to keep looking
    into it, though, so let me know if you find anything either.

    Out of curiosity, what is this project you're working on?

    --
    |\/| /| |2 |<
    mehaase(at)sas(dot)upenn(dot)edu
    Mark Guest

  8. #8

    Default Re: C calls to set login item.

    Mark Haase <net> wrote:
     

    Look at:

    ~/Library/Preferences/loginwindow.plist

    You can manipulate the file using NSUserDefaults or CFPreferences.

    Have fun,

    Patrick Machielse
    ---
    Hieper Software
    The Netherlands
    Patrick Guest

  9. #9

    Default Re: C calls to set login item.

    In article <upenn.edu>,
    Mark Haase <net> wrote:
     

    If all you need is the sample code, they might send it to you even if
    you're only registered to ADC online.

    Patrick
    --
    Patrick Stadelmann <ch>
    Patrick Guest

  10. #10

    Default Re: C calls to set login item.

    On Fri, 6 Feb 2004, Andew wrote:
     
    > >
    > > E-Mail Apple's Developer Technical support (their username on apple.com
    > > is "dts"). They have some "Login Items API" sample code that does what
    > > you want. (no, there is no real login items API)[/ref]
    >
    > Thanks for the response. But I'm not registered with Apple. And since I
    > don't pay them for tech support I don't really have the right to email
    > them with my questions. I was hoping for a few hints - just enough for
    > me to figure out how to start this.
    >[/ref]
    It doesn't matter. they have a sample that's ready to use (well apart from
    using ascii for paths, and it doesn't store aliases to the items, just
    paths). You might possibly need to register as a ADC
    online member, but that's free.
     
    that could be a problem as the code is NDA'd
     

    The whole sample is just a bit of monkeying around with cfpreferences. you
    could probably work it out by looking at ~/Library/loginwindow.plist


    Fred 

    Frederick Guest

  11. #11

    Default Re: C calls to set login item. (SUCCESS!!)

    > Look at: 

    Ah ... that's it. That's the piece that I was missing. All I needed was
    this and I got the solution that I needed. (I've included the code that
    I came up with at the end of this email so that maybe others could learn
    and improve.)

    I've include my code and some examples on how to use it. It's not the
    greatest code but it works for me. Hopefully others will find some use
    in what I've included. There's not a lot of comments so I hope that what
    I've done makes sense.

    Thanks for spilling this last piece of the puzzle. It took some effort
    but I love working at code until I get it working. It's a wonderful
    sense of achievement.

    Andrew

    ******************************

    /*

    The login items are stored in: ~/Library/Preferences/loginwindow.plist
    which will be refered to as "loginwindow" from here on.

    In the following, it is _assumed_ that the loginwindow file looks
    something like:

    .... usual xml/plist declarations ...
    <dict>
    <key>AutoLaunchedApplicationDictionary</key>
    <array>
    <dict>
    <key>Hide</key>
    <false/>
    <key>Path</key>
    <string>/Applications/TextEdit.app</string>
    </dict>
    </array>
    ... other stuff ...
    <dict>

    This structure affects the way that we work with the data.

    We must remember that we are not the only people accessing this file and
    that errors
    could cause problems for everyone. Let's do the right thing and be very
    considerate
    of other applications that might make use of this file to start their
    applications.

    */

    BOOL CAIsApplicationALoginItem( CFStringRef appName )
    {
    BOOL isLoginItem = FALSE;

    CFStringRef applicationID = CFSTR("loginwindow");
    CFStringRef autoLaunchKey =
    CFSTR("AutoLaunchedApplicationDictionary");
    CFPropertyListRef autoLaunchValue = CFPreferencesCopyAppValue(
    autoLaunchKey, applicationID );

    if ( autoLaunchValue )
    {
    if ( CFGetTypeID( autoLaunchValue ) == CFArrayGetTypeID() )
    {
    CFStringRef pathKey = CFSTR("Path");
    CFArrayRef autoLaunchArray = (CFArrayRef)autoLaunchValue;
    CFIndex i, arraySize = CFArrayGetCount( autoLaunchArray );

    for ( i = 0; i < arraySize; i++ )
    {
    CFDictionaryRef itemDict =
    (CFDictionaryRef)CFArrayGetValueAtIndex( autoLaunchArray, i );
    if ( itemDict )
    {
    CFStringRef pathStr = (CFStringRef)CFDictionaryGetValue(
    itemDict, pathKey );
    if ( pathStr )
    {
    NSString *tmpName = [ (NSString *)pathStr
    lastPathComponent ];
    if ( [ tmpName isEqualToString:(NSString *)appName ] )
    {
    isLoginItem = TRUE;
    }
    }
    }
    }
    }
    CFRelease( autoLaunchValue );
    }

    return isLoginItem;
    }

    void CARemoveApplicationFromLoginItems( CFStringRef appName )
    {
    CFStringRef applicationID = CFSTR("loginwindow");
    CFStringRef autoLaunchKey =
    CFSTR("AutoLaunchedApplicationDictionary");
    CFPropertyListRef autoLaunchValue = CFPreferencesCopyAppValue(
    autoLaunchKey, applicationID );

    if ( autoLaunchValue )
    {
    if ( CFGetTypeID( autoLaunchValue ) == CFArrayGetTypeID() )
    {
    CFStringRef pathKey = CFSTR("Path");
    CFArrayRef autoLaunchArray = (CFArrayRef)autoLaunchValue;
    CFIndex i, arraySize = CFArrayGetCount( autoLaunchArray );

    for ( i = 0; i < arraySize; i++ )
    {
    CFDictionaryRef itemDict =
    (CFDictionaryRef)CFArrayGetValueAtIndex( autoLaunchArray, i );
    if ( itemDict )
    {
    CFStringRef pathStr = (CFStringRef)CFDictionaryGetValue(
    itemDict, pathKey );
    if ( pathStr )
    {
    NSString *tmpName = [ (NSString *)pathStr
    lastPathComponent ];
    if ( [ tmpName isEqualToString:(NSString *)appName ] )
    {
    CFMutableArrayRef newArray =
    CFArrayCreateMutableCopy( NULL, 0, autoLaunchArray );
    if ( newArray )
    {
    CFArrayRemoveValueAtIndex( newArray, i );
    CFPreferencesSetAppValue( autoLaunchKey,
    newArray, applicationID );
    CFPreferencesAppSynchronize( applicationID );
    CFRelease( newArray );
    i = arraySize; // kill the looping
    }
    }
    }
    }
    }
    }

    CFRelease( autoLaunchValue );
    }
    }

    void CAAddApplicationToLoginItems( CFStringRef appPath )
    {
    if ( CAIsApplicationALoginItem( (CFStringRef)[ (NSString *)appPath
    lastPathComponent ] ) == FALSE ) // Only add if the application is NOT
    already there.
    {
    CFStringRef applicationID = CFSTR("loginwindow");
    CFStringRef autoLaunchKey =
    CFSTR("AutoLaunchedApplicationDictionary");
    CFPropertyListRef autoLaunchValue = CFPreferencesCopyAppValue(
    autoLaunchKey, applicationID );

    if ( autoLaunchValue )
    {
    if ( CFGetTypeID( autoLaunchValue ) == CFArrayGetTypeID() )
    {
    CFArrayRef autoLaunchArray = (CFArrayRef)autoLaunchValue;
    CFMutableArrayRef newArray = CFArrayCreateMutableCopy( NULL,
    0, autoLaunchArray );
    if ( newArray )
    {
    CFMutableDictionaryRef newDict =
    CFDictionaryCreateMutable( NULL, 0, NULL, NULL );
    if ( newDict )
    {
    CFStringRef hideStr = CFSTR("Hide");
    CFStringRef pathStr = CFSTR("Path");

    CFDictionaryAddValue( newDict, hideStr,
    kCFBooleanFalse );
    CFDictionaryAddValue( newDict, pathStr, appPath );

    CFArrayAppendValue ( newArray, newDict );
    CFPreferencesSetAppValue( autoLaunchKey, newArray,
    applicationID );
    CFPreferencesAppSynchronize( applicationID );

    CFRelease( newDict );
    }
    CFRelease( newArray );
    }
    }
    CFRelease( autoLaunchValue );
    }
    }
    }

    /////////////
    // Usage

    BOOL IsAutostart()
    {
    NSString *appPath = [ [ [ NSBundle mainBundle ] executablePath ]
    stringByDeletingLastPathComponent ];
    appPath = [ [ appPath stringByDeletingLastPathComponent ]
    stringByDeletingLastPathComponent ];

    return CAIsApplicationALoginItem( (CFStringRef)[ appPath
    lastPathComponent ] );
    }

    void SetAutostart( bool shouldStart )
    {
    NSString *appPath = [ [ [ NSBundle mainBundle ] executablePath ]
    stringByDeletingLastPathComponent ];
    appPath = [ [ appPath stringByDeletingLastPathComponent ]
    stringByDeletingLastPathComponent ];

    if ( shouldStart )
    {
    CAAddApplicationToLoginItems( (CFStringRef)appPath );
    }
    else
    {
    CARemoveApplicationFromLoginItems( (CFStringRef)[ appPath
    lastPathComponent ] );
    }
    }
    Andew Guest

  12. #12

    Default Re: C calls to set login item. (SUCCESS!!)

    Andrew,

    your code work perfectly.

    Thank a lot.


    In article <ihug.co.nz>, Andew
    <com> wrote:
     
    >
    > Ah ... that's it. That's the piece that I was missing. All I needed was
    > this and I got the solution that I needed. (I've included the code that
    > I came up with at the end of this email so that maybe others could learn
    > and improve.)
    >
    > I've include my code and some examples on how to use it. It's not the
    > greatest code but it works for me. Hopefully others will find some use
    > in what I've included. There's not a lot of comments so I hope that what
    > I've done makes sense.
    >
    > Thanks for spilling this last piece of the puzzle. It took some effort
    > but I love working at code until I get it working. It's a wonderful
    > sense of achievement.
    >
    > Andrew
    >
    > ******************************
    >
    > /*
    >
    > The login items are stored in: ~/Library/Preferences/loginwindow.plist
    > which will be refered to as "loginwindow" from here on.
    >
    > In the following, it is _assumed_ that the loginwindow file looks
    > something like:
    >
    > ... usual xml/plist declarations ...
    > <dict>
    > <key>AutoLaunchedApplicationDictionary</key>
    > <array>
    > <dict>
    > <key>Hide</key>
    > <false/>
    > <key>Path</key>
    > <string>/Applications/TextEdit.app</string>
    > </dict>
    > </array>
    > ... other stuff ...
    > <dict>
    >
    > This structure affects the way that we work with the data.
    >
    > We must remember that we are not the only people accessing this file and
    > that errors
    > could cause problems for everyone. Let's do the right thing and be very
    > considerate
    > of other applications that might make use of this file to start their
    > applications.
    >
    > */
    >
    > BOOL CAIsApplicationALoginItem( CFStringRef appName )
    > {
    > BOOL isLoginItem = FALSE;
    >
    > CFStringRef applicationID = CFSTR("loginwindow");
    > CFStringRef autoLaunchKey =
    > CFSTR("AutoLaunchedApplicationDictionary");
    > CFPropertyListRef autoLaunchValue = CFPreferencesCopyAppValue(
    > autoLaunchKey, applicationID );
    >
    > if ( autoLaunchValue )
    > {
    > if ( CFGetTypeID( autoLaunchValue ) == CFArrayGetTypeID() )
    > {
    > CFStringRef pathKey = CFSTR("Path");
    > CFArrayRef autoLaunchArray = (CFArrayRef)autoLaunchValue;
    > CFIndex i, arraySize = CFArrayGetCount( autoLaunchArray );
    >
    > for ( i = 0; i < arraySize; i++ )
    > {
    > CFDictionaryRef itemDict =
    > (CFDictionaryRef)CFArrayGetValueAtIndex( autoLaunchArray, i );
    > if ( itemDict )
    > {
    > CFStringRef pathStr = (CFStringRef)CFDictionaryGetValue(
    > itemDict, pathKey );
    > if ( pathStr )
    > {
    > NSString *tmpName = [ (NSString *)pathStr
    > lastPathComponent ];
    > if ( [ tmpName isEqualToString:(NSString *)appName ] )
    > {
    > isLoginItem = TRUE;
    > }
    > }
    > }
    > }
    > }
    > CFRelease( autoLaunchValue );
    > }
    >
    > return isLoginItem;
    > }
    >
    > void CARemoveApplicationFromLoginItems( CFStringRef appName )
    > {
    > CFStringRef applicationID = CFSTR("loginwindow");
    > CFStringRef autoLaunchKey =
    > CFSTR("AutoLaunchedApplicationDictionary");
    > CFPropertyListRef autoLaunchValue = CFPreferencesCopyAppValue(
    > autoLaunchKey, applicationID );
    >
    > if ( autoLaunchValue )
    > {
    > if ( CFGetTypeID( autoLaunchValue ) == CFArrayGetTypeID() )
    > {
    > CFStringRef pathKey = CFSTR("Path");
    > CFArrayRef autoLaunchArray = (CFArrayRef)autoLaunchValue;
    > CFIndex i, arraySize = CFArrayGetCount( autoLaunchArray );
    >
    > for ( i = 0; i < arraySize; i++ )
    > {
    > CFDictionaryRef itemDict =
    > (CFDictionaryRef)CFArrayGetValueAtIndex( autoLaunchArray, i );
    > if ( itemDict )
    > {
    > CFStringRef pathStr = (CFStringRef)CFDictionaryGetValue(
    > itemDict, pathKey );
    > if ( pathStr )
    > {
    > NSString *tmpName = [ (NSString *)pathStr
    > lastPathComponent ];
    > if ( [ tmpName isEqualToString:(NSString *)appName ] )
    > {
    > CFMutableArrayRef newArray =
    > CFArrayCreateMutableCopy( NULL, 0, autoLaunchArray );
    > if ( newArray )
    > {
    > CFArrayRemoveValueAtIndex( newArray, i );
    > CFPreferencesSetAppValue( autoLaunchKey,
    > newArray, applicationID );
    > CFPreferencesAppSynchronize( applicationID );
    > CFRelease( newArray );
    > i = arraySize; // kill the looping
    > }
    > }
    > }
    > }
    > }
    > }
    >
    > CFRelease( autoLaunchValue );
    > }
    > }
    >
    > void CAAddApplicationToLoginItems( CFStringRef appPath )
    > {
    > if ( CAIsApplicationALoginItem( (CFStringRef)[ (NSString *)appPath
    > lastPathComponent ] ) == FALSE ) // Only add if the application is NOT
    > already there.
    > {
    > CFStringRef applicationID = CFSTR("loginwindow");
    > CFStringRef autoLaunchKey =
    > CFSTR("AutoLaunchedApplicationDictionary");
    > CFPropertyListRef autoLaunchValue = CFPreferencesCopyAppValue(
    > autoLaunchKey, applicationID );
    >
    > if ( autoLaunchValue )
    > {
    > if ( CFGetTypeID( autoLaunchValue ) == CFArrayGetTypeID() )
    > {
    > CFArrayRef autoLaunchArray = (CFArrayRef)autoLaunchValue;
    > CFMutableArrayRef newArray = CFArrayCreateMutableCopy( NULL,
    > 0, autoLaunchArray );
    > if ( newArray )
    > {
    > CFMutableDictionaryRef newDict =
    > CFDictionaryCreateMutable( NULL, 0, NULL, NULL );
    > if ( newDict )
    > {
    > CFStringRef hideStr = CFSTR("Hide");
    > CFStringRef pathStr = CFSTR("Path");
    >
    > CFDictionaryAddValue( newDict, hideStr,
    > kCFBooleanFalse );
    > CFDictionaryAddValue( newDict, pathStr, appPath );
    >
    > CFArrayAppendValue ( newArray, newDict );
    > CFPreferencesSetAppValue( autoLaunchKey, newArray,
    > applicationID );
    > CFPreferencesAppSynchronize( applicationID );
    >
    > CFRelease( newDict );
    > }
    > CFRelease( newArray );
    > }
    > }
    > CFRelease( autoLaunchValue );
    > }
    > }
    > }
    >
    > /////////////
    > // Usage
    >
    > BOOL IsAutostart()
    > {
    > NSString *appPath = [ [ [ NSBundle mainBundle ] executablePath ]
    > stringByDeletingLastPathComponent ];
    > appPath = [ [ appPath stringByDeletingLastPathComponent ]
    > stringByDeletingLastPathComponent ];
    >
    > return CAIsApplicationALoginItem( (CFStringRef)[ appPath
    > lastPathComponent ] );
    > }
    >
    > void SetAutostart( bool shouldStart )
    > {
    > NSString *appPath = [ [ [ NSBundle mainBundle ] executablePath ]
    > stringByDeletingLastPathComponent ];
    > appPath = [ [ appPath stringByDeletingLastPathComponent ]
    > stringByDeletingLastPathComponent ];
    >
    > if ( shouldStart )
    > {
    > CAAddApplicationToLoginItems( (CFStringRef)appPath );
    > }
    > else
    > {
    > CARemoveApplicationFromLoginItems( (CFStringRef)[ appPath
    > lastPathComponent ] );
    > }
    > }[/ref]
    Alain Guest

  13. #13

    Default Re: C calls to set login item. (SUCCESS!!)

    > Andrew, 

    No worries. Although I tested it as hard as I could, it's good to hear
    that it works for others.

    It made sense to share my final efforts with this group as it was
    through this group that I got the hints needed to work my way out of a
    stuck position.

    Thanks everyone.

    Andrew
    Andew Guest

Similar Threads

  1. e.Item.ItemIndex and e.Item.DataSetIndex
    By Scott M. in forum ASP.NET Data Grid Control
    Replies: 5
    Last Post: April 13th, 05:40 AM
  2. Replies: 2
    Last Post: February 5th, 12:11 AM
  3. Replies: 6
    Last Post: January 17th, 07:46 PM
  4. Replies: 1
    Last Post: November 24th, 08:24 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139