views:

771

answers:

3

Does anyone know how to programmatically access the "All Users" Startup Menu?

In XP, located here:

C:\Documents and Settings\All Users\Start Menu\Programs\Startup

And in Windows 7, located here:

C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup

Specifically, I've got a Setup and Deployment project, and I'd like to put a shortcut to the application in the Startup menu for all users so that the application is start whenever anyone logs in.

EDIT: I'm pretty sure this is where Brian got his answer from.

+2  A: 

"All Users" resides in the ALLUSERSPROFILE environment variable:

C:\>dir "%ALLUSERSPROFILE%\Start Menu"
 Volume in drive C is awesome
 Volume Serial Number is 8C57-DB1A

 Directory of C:\Documents and Settings\All Users\Start Menu

12/28/2009  10:27 PM    <DIR>          .
12/28/2009  10:27 PM    <DIR>          ..
12/28/2009  10:01 PM             1,566 Microsoft Update.lnk
02/23/2010  09:57 PM    <DIR>          Programs
12/28/2009  10:27 PM             1,563 Set Program Access and Defaults.lnk
12/28/2009  08:51 PM               398 Windows Catalog.lnk
12/28/2009  08:51 PM             1,507 Windows Update.lnk
               4 File(s)          5,034 bytes
               3 Dir(s)  64,214,460,416 bytes free
Seth
This may not work depending on the locale of the Windows installed.
Brian R. Bondy
Doesn't work with Windows 7.
fre0n
@fre0n I don't work with Windows 7 either.
Seth
It actually works on Windows 7, but it doesn't point to the Startup folder.
0xA3
+5  A: 

There is no constant defined for the normal way of Environment.GetFolderPath for the all users start menu, but you can do it this way by using the Win32 API SHGetSpecialFolderPath:

class Program
{
    [DllImport("shell32.dll")]
    static extern bool SHGetSpecialFolderPath(IntPtr hwndOwner,
       [Out] StringBuilder lpszPath, int nFolder, bool fCreate);
    const int CSIDL_COMMON_STARTMENU = 0x16;  // \Windows\Start Menu\Programs

    static void Main(string[] args)
    {
        StringBuilder path = new StringBuilder(260);
        SHGetSpecialFolderPath(IntPtr.Zero, path, CSIDL_COMMON_STARTMENU, false);
        string s = path.ToString();
    }
}
Brian R. Bondy
I wish I didn't have to use the Win32 API, but this does the job.
fre0n
Very common to have to use the Win32 API from C# :)
Brian R. Bondy
@fre0n: If you don't want to use Win32 API you can use the MSI properties made for that purpose.
0xA3
+2  A: 

You can access the startup folder using the appropriate MSI property (see here for more details): [StartupFolder]

However, as typical for user-dependent MSI variables, this property points either to the user's startup folder or the all users' startup folder, depending on the value of the ALLUSERS property.

This means that when you install for "Everyone" (per-machine) you will get the folder

C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\

otherwise you will the per-user folder within the user's profile. This is by design and also makes sense, as a per-user installation will not have permission to write to the all users folder.

In your Setup and Deployment project, do the following to place files into the startup folder:

  • open the File System view,
  • right-click the folder tree and add a custom folder.
  • under the properties of this folder, set DefaultLocation to [StartupFolder]
  • add the content to the custom folder
0xA3