• 0

C#: Get path of Start Menu programs (All USERS)


Question

hi guys

does anyone know how can i get the path of the start menu under All Users (X:\Documents and Settings\All Users\Start Menu\Programs) ?

i tried :

DirectoryInfo di = new DirectoryInfo(System.Environment.G? etFolderPath(Environment.SpecialFo? lder.Programs));

but that only gives the Path for current user. How can i get to the All Users start menu?

12 answers to this question

Recommended Posts

  • 0

The built-in .Net methods are underdeveloped, IMO. Use WinAPI.

See here for the function SHGetSpecialFolderPath, and a link to the list of CSIDL's you can use.

http://msdn2.microsoft.com/en-us/library/ms647816.aspx

Here's the function import and a sample on how to use it:

[DllImport("shell32.dll")]
static extern bool SHGetSpecialFolderPath(IntPtr hwndOwner,
   [Out] StringBuilder lpszPath, int nFolder, bool fCreate);

const int CSIDL_PROGRAMS = 2;  // \Windows\Start Menu\Programs
StringBuilder path = new StringBuilder(260);
SHGetSpecialFolderPath(IntPtr.Zero, path, CSIDL_PROGRAMS, false);
// path.ToString() should now hold the path

Here's the full list of CSIDL's from ShlObj.h

const int CSIDL_DESKTOP 					= 0x0000;		// <desktop>
const int CSIDL_INTERNET					= 0x0001;		// Internet Explorer (icon on desktop)
const int CSIDL_PROGRAMS					  = 0x0002;		// Start Menu\Programs
const int CSIDL_CONTROLS					  = 0x0003;		// My Computer\Control Panel
const int CSIDL_PRINTERS					  = 0x0004;		// My Computer\Printers
const int CSIDL_PERSONAL					  = 0x0005;		// My Documents
const int CSIDL_FAVORITES				 	= 0x0006;		// <user name>\Favorites
const int CSIDL_STARTUP				   	= 0x0007;		// Start Menu\Programs\Startup
const int CSIDL_RECENT					  = 0x0008;		// <user name>\Recent
const int CSIDL_SENDTO					  = 0x0009;		// <user name>\SendTo
const int CSIDL_BITBUCKET				   = 0x000a;		// <desktop>\Recycle Bin
const int CSIDL_STARTMENU				   = 0x000b;		// <user name>\Start Menu
const int CSIDL_MYDOCUMENTS				 = CSIDL_PERSONAL; //  Personal was just a silly name for My Documents
const int CSIDL_MYMUSIC					 = 0x000d;		// "My Music" folder
const int CSIDL_MYVIDEO					 = 0x000e;		// "My Videos" folder
const int CSIDL_DESKTOPDIRECTORY			= 0x0010;		// <user name>\Desktop
const int CSIDL_DRIVES					  = 0x0011;		// My Computer
const int CSIDL_NETWORK					 = 0x0012;		// Network Neighborhood (My Network Places)
const int CSIDL_NETHOOD					 = 0x0013;		// <user name>\nethood
const int CSIDL_FONTS					   = 0x0014;		// windows\fonts
const int CSIDL_TEMPLATES				   = 0x0015;
const int CSIDL_COMMON_STARTMENU			= 0x0016;		// All Users\Start Menu
const int CSIDL_COMMON_PROGRAMS			 = 0x0017;		// All Users\Start Menu\Programs
const int CSIDL_COMMON_STARTUP			  = 0x0018;		// All Users\Startup
const int CSIDL_COMMON_DESKTOPDIRECTORY	 = 0x0019;		// All Users\Desktop
const int CSIDL_APPDATA					 = 0x001a;		// <user name>\Application Data
const int CSIDL_PRINTHOOD				   = 0x001b;		// <user name>\PrintHood
const int CSIDL_LOCAL_APPDATA			   = 0x001c;		// <user name>\Local Settings\Applicaiton Data (non roaming)
const int CSIDL_ALTSTARTUP				  = 0x001d;		// non localized startup
const int CSIDL_COMMON_ALTSTARTUP		   = 0x001e;		// non localized common startup
const int CSIDL_COMMON_FAVORITES			= 0x001f;
const int CSIDL_INTERNET_CACHE			  = 0x0020;
const int CSIDL_COOKIES					 = 0x0021;
const int CSIDL_HISTORY					 = 0x0022;
const int CSIDL_COMMON_APPDATA			  = 0x0023;		// All Users\Application Data
const int CSIDL_WINDOWS					 = 0x0024;		// GetWindowsDirectory()
const int CSIDL_SYSTEM					  = 0x0025;		// GetSystemDirectory()
const int CSIDL_PROGRAM_FILES			   = 0x0026;		// C:\Program Files
const int CSIDL_MYPICTURES				  = 0x0027;		// C:\Program Files\My Pictures
const int CSIDL_PROFILE					 = 0x0028;		// USERPROFILE
const int CSIDL_SYSTEMX86				   = 0x0029;		// x86 system directory on RISC
const int CSIDL_PROGRAM_FILESX86			= 0x002a;		// x86 C:\Program Files on RISC
const int CSIDL_PROGRAM_FILES_COMMON		= 0x002b;		// C:\Program Files\Common
const int CSIDL_PROGRAM_FILES_COMMONX86	 = 0x002c;		// x86 Program Files\Common on RISC
const int CSIDL_COMMON_TEMPLATES			= 0x002d;		// All Users\Templates
const int CSIDL_COMMON_DOCUMENTS			= 0x002e;		// All Users\Documents
const int CSIDL_COMMON_ADMINTOOLS		   = 0x002f;		// All Users\Start Menu\Programs\Administrative Tools
const int CSIDL_ADMINTOOLS				  = 0x0030;		// <user name>\Start Menu\Programs\Administrative Tools
const int CSIDL_CONNECTIONS				 = 0x0031;		// Network and Dial-up Connections
const int CSIDL_COMMON_MUSIC				= 0x0035;		// All Users\My Music
const int CSIDL_COMMON_PICTURES			 = 0x0036;		// All Users\My Pictures
const int CSIDL_COMMON_VIDEO				= 0x0037;		// All Users\My Video
const int CSIDL_RESOURCES				   = 0x0038;		// Resource Direcotry
const int CSIDL_RESOURCES_LOCALIZED		 = 0x0039;		// Localized Resource Direcotry
const int CSIDL_COMMON_OEM_LINKS			= 0x003a;		// Links to All Users OEM specific apps
const int CSIDL_CDBURN_AREA				 = 0x003b;		// USERPROFILE\Local Settings\Application Data\Microsoft\CD Burning
const int CSIDL_COMPUTERSNEARME			 = 0x003d;		// Computers Near Me (computered from Workgroup membership)
const int CSIDL_FLAG_CREATE				 = 0x8000;		// combine with CSIDL_ value to force folder creation in SHGetFolderPath()
const int CSIDL_FLAG_DONT_VERIFY			= 0x4000;		// combine with CSIDL_ value to return an unverified folder path
const int CSIDL_FLAG_DONT_UNEXPAND		  = 0x2000;		// combine with CSIDL_ value to avoid unexpanding environment variables
const int CSIDL_FLAG_NO_ALIAS			   = 0x1000;		// combine with CSIDL_ value to insure non-alias versions of the pidl
const int CSIDL_FLAG_PER_USER_INIT		  = 0x0800;		// combine with CSIDL_ value to indicate per-user init (eg. upgrade)

Note that this was quickly converted from the C++ headers to C#, so there may be simple formatting errors, but all of the data is correct.

Edited by jimbo11883
  • 0

Environment.GetEnvironmentVariable("ALLUSERSPROFILE")

return a string "DRIVE:\Documents and Settings\All Users" (from wikipedia), from there you should beable to get to the StartMenu\Programs

It doesnt work for me but im on Vista, all i get is an hidden folder called ProgramData.It might work on XP.

if not then switch "ALLUSERSPROFILE" with "HOMEDRIVE" and you will get just the drive windows is install on example "C:\" from there you can work your way to where you want to go.

Edited by Doli
  • 0
  On 27/01/2010 at 15:41, garethevans1986 said:

Dude this is like 2 years old!

yeah i know, but google found it when i was searching for this solution....

the code that i sent are only usable if you're looking for the user folders, if you need the Common folders, read this:

http://www.codeproject.com/KB/winsdk/SpecialFolders.aspx

  • 0
  On 27/01/2010 at 11:38, Tufo said:

I know its a late reply, but for ppl that find this post on google (like me) its quite simple to find the start menu folder:

String startMenuPath = Environment.GetFolderPath(Environment.SpecialFolder.StartMenu);

That returns the path for the current user's start menu startup.

  On 27/01/2010 at 15:41, garethevans1986 said:

Dude this is like 2 years old!

He apologized for the late reply and contributed something, what's the problem?

Thanks Tufo, I'm just working through the same problem. I think Jimbo's method is probably most reliable.

  • 0

99.9% of thread being replied to after being "dead" for 2+ years are either troll threads or spammers....

Granted, like you said this poster posted something relevant!

GE

  • 0

This thread may be 3 years old but no one has posted the correct answer yet.

Typically you would use

Environment.GetFolderPath

, but there is no constant defined for it.

Here is the correct solution using a Win32 API:

  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();
        }
    }

  • 0
  Quote
but there is no constant defined for it
Sure there is; in .NET 4 :)

Just like with registry access, the .NET implementation of the FolderPath APIs is lacking through version 3.5 SP1. However, starting with .NET 4.0, you can do the following:

Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu)

Edit: the CODE tags screw up the character casing a little bit; the "s" should be capitalized

Edit 2: WTF, it's impossible to capitalize all three parts of that word anywhere in a forum post. Weird.

It would be nice if they would consider community contribution to the BCL for simple things like this. It's just an enum value and we shouldn't have to wrap 10 year-old APIs in P/Invoke (CSIDL_COMMON_STARTMENU has been available natively starting with XP). Actually, on closer look, it appears this was even defined in Windows 2000.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • New Outlook for Windows gets a major boost with June 2025 Update by Pradeep Viswanathan Despite widespread criticism, Microsoft has remained focused on replacing the classic Outlook for Windows with the new web-based Outlook app for everyone. Every month, Microsoft releases updates to the new Outlook app based on user feedback. Today, Microsoft released the June 2025 update for Outlook for Windows with several improvements, including some of the most requested features by Outlook users. With this latest update, Microsoft has improved support for .pst (Outlook Data File) files. You can now reply to and forward emails in a stored .pst file. Microsoft is also working on further improving support for .pst files in the new Outlook for Windows. If you're using the new Outlook app with your personal Microsoft account that has access to Copilot Pro or AI credits through a Microsoft 365 Personal or Family subscription, Copilot features will now be available even for other personal email accounts configured in the Outlook app. This Copilot sharing feature works with email addresses such as Outlook.com, Hotmail.com, Live.com, MSN.com, and third-party providers like Gmail, Yahoo, and iCloud. Microsoft has also added the ability to easily move emails between personal accounts. This feature is disabled by default for enterprise users, but admins can enable it if needed. With this update, Microsoft has increased the default mail sync window in offline mode from 7 days to 30 days. Additionally, you can now access search folders and cancel an email after selecting Send in offline mode. This new update also brings email coaching support through Copilot. Copilot can now suggest adjustments to tone, clarity, and reader sentiment before you hit Send. If you are annoyed with Copilot, you can now disable Copilot completely by going to the Copilot > Copilot control page in the Settings window. In this release, Microsoft has added the ability to add shared folders to your Favorites, making it easier to access content directly from the Favorites list. Finally, an "External" tag will be added to external contact suggestions that appear in the dropdown menu when entering contacts in the email compose form, helping you distinguish between your organization's and external contacts.
    • "give" I believe he will give loans and drown the countries in debt
    • Minor Problems over the years with Windows 11 Pro on my original Intel 10700 Desktop i was using and not many problems on my Newer AMD Ryzen 7 7700X. Overall Windows 11 works extremely well, if don't do too many modifications, and do the regular security updates, and keep 3rd party apps up to date, and users shouldn't have any issues, and if a user does, should be a minor little issue that is easily fixable My goal is to have the 2 remaining household systems replaced for Windows 11 Compatible machines, hopefully by early September if not sooner.
    • Bill Gates says he'll donate 99 percent of his wealth to Africa by Hamid Ganji Microsoft co-founder and tech billionaire Bill Gates has pledged to donate a significant chunk of his personal wealth to African countries. As reported by the BBC, Gates's funding will be spent on improving health and education infrastructure in Africa over the next twenty years. The Gates Foundation has played an active role in improving public health and education in Africa over the past decades. Bill Gates aims to double down on that effort by donating most of his fortune to Africa. Last month, he also said that 99% of his fortune, which could exceed $200 billion, will go to African countries by 2045. Speaking at the African Union (AU) headquarters in Ethiopia's capital, Addis Ababa, Gates said, "By unleashing human potential through health and education, every country in Africa should be on a path to prosperity." The tech billionaire also told young African innovators to start relying on AI to improve health and education in their countries and use the technology to benefit the entire continent. He introduced Rwanda as a successful example of using AI in healthcare to identify high-risk pregnancies. "Africa largely skipped traditional banking and now you have a chance, as you build your next generation healthcare systems, to think about how AI is built into that," Gates added. By donating 99 percent of his personal fortune by 2045, Bill Gates can still maintain his position as one of the richest people on earth. According to Bloomberg, Gates's current net worth is around $175 billion. Gates's decision to donate 99 percent of his wealth to Africa came after the US administration cut USAID funding to African countries following the DOGE investigations. In a recent interview with the New York Times, Bill Gates called out Elon Musk for cutting the USAID budget, saying Musk has a role in the death of the poorest children on earth.
  • Recent Achievements

    • Week One Done
      Adam Todd earned a badge
      Week One Done
    • Contributor
      Ed B went up a rank
      Contributor
    • One Month Later
      moporcho earned a badge
      One Month Later
    • One Month Later
      Parotel earned a badge
      One Month Later
    • Reacting Well
      Cryptecks earned a badge
      Reacting Well
  • Popular Contributors

    1. 1
      +primortal
      202
    2. 2
      snowy owl
      146
    3. 3
      ATLien_0
      134
    4. 4
      Xenon
      120
    5. 5
      +FloatingFatMan
      113
  • Tell a friend

    Love Neowin? Tell a friend!