none
Can I use KnownFolderIDs from vbscript

    Question

  • I use vbscript - NOT powershell - to support over 100,000 devices worldwide. These devices range from Windows 8 eval machines to windows 7, some Vista, TONS on XP and I'm sure a few W2K stragglers out there. These machines are all different languages. We even had to move to unicode log files to support some of the Asian language characters.

    I wan't to be able to use the new KnownFolders in place of CSIDL values on the newer devices as suggested in this KB article:

    http://msdn.microsoft.com/en-us/library/bb776911(v=vs.85).aspx

    I can't find a way to resolve these knownfolder paths from vbscript. Is there a way to do this?

    Thanks,

    Gerry


    Wednesday, January 02, 2013 7:12 PM

Answers

  • For an object to be accessible as an ActiveX (COM) automation object, it must implement the IDispatch interface. WSH-based scripts only support automation objects.

    IKnownFolder inherits from IUnknown, and I don't see any mention of it having an IDispatch interface. Thus, IKnownFolder would not be accessible from a VBScript WSH script.

    Bill

    • Marked as answer by Gerry Michaud Thursday, January 03, 2013 2:25 PM
    Wednesday, January 02, 2013 8:43 PM

All replies

  • "Special" folders are supported by the Shell.Application object in VBScript. See this link:

    http://technet.microsoft.com/en-us/library/ee176604.aspx

    Does this help?


    Richard Mueller - MVP Directory Services

    Wednesday, January 02, 2013 8:01 PM
  • Shell.Application uses only CSIDL values.

    Currently only the IKnownFolderManager interface exposes a GetFolder method that uses the newer GUID references.  This interface is not callable from COM based scripting engines.

    There is a way to use PowerShell to access this interface.

    Currently there is no reason to use this.  All folders are currently exposed in both enumerations.  I am reasonably certain that Shell.Application will continue to work for quite some time.

    It is likely that all future access will be through dotNet and will not be extended to COM based language.  Time to start planning to convert to PowerShell.  This will likely take as much as two years of careful migration.  Do not migrate all scripts. Just pick those areas where future changes will be needed.


    Happy New Year ¯\_(ツ)_/¯



    • Edited by jrv Thursday, January 03, 2013 2:08 AM
    Wednesday, January 02, 2013 8:14 PM
  • Thanks Richard, but I have code for 'special' folders (the CSIDLs).

    KnownFolders were introduced with Vista and supercede CSIDL values. They would allow, for instance, retrieving a (language-specific) path to the user's documents library, presumably the default folder of that library. It is these new features I am trying to access, to 'kick the tires' so to speak and see what they provide that I can make use of. There are no CSIDLs for the libraries, and many other folders.

    By my count there are 68 CSIDLs (including 6 special FLAGs) and 121 KnownFolderID values (GUIDs) (including 10 special FLAGs)

    http://msdn.microsoft.com/en-us/library/dd378457(v=vs.85).aspx

    If you can find a way to access these values via vbscript I would be very interested in seeing some code. I have these links, but no code I can use.

    http://msdn.microsoft.com/en-us/library/bb762188(v=vs.85).aspx

    http://msdn.microsoft.com/en-us/library/bb761762(v=vs.85).aspx

    FYI, Here is the list of KnownFolderIDs that I have found that have no CSIDL equivalent:

    FOLDERID_AddNewPrograms
    FOLDERID_AppUpdates
    FOLDERID_ChangeRemovePrograms
    FOLDERID_ConflictFolder
    FOLDERID_Contacts
    FOLDERID_DeviceMetadataStore
    FOLDERID_DocumentsLibrary
    FOLDERID_Downloads
    FOLDERID_Games
    FOLDERID_GameTasks
    FOLDERID_HomeGroup
    FOLDERID_ImplicitAppShortcuts
    FOLDERID_Libraries
    FOLDERID_Links
    FOLDERID_LocalAppDataLow
    FOLDERID_MusicLibrary
    FOLDERID_OriginalImages
    FOLDERID_PhotoAlbums
    FOLDERID_PicturesLibrary
    FOLDERID_Playlists
    FOLDERID_ProgramFilesCommonX64
    FOLDERID_ProgramFilesX64
    FOLDERID_Public
    FOLDERID_PublicDownloads
    FOLDERID_PublicGameTasks
    FOLDERID_PublicLibraries
    FOLDERID_PublicRingtones
    FOLDERID_QuickLaunch
    FOLDERID_RecordedTVLibrary
    FOLDERID_Ringtones
    FOLDERID_SampleMusic     
    FOLDERID_SamplePictures  
    FOLDERID_SamplePlaylists 
    FOLDERID_SampleVideos    
    FOLDERID_SavedGames      
    FOLDERID_SavedSearches   
    FOLDERID_SEARCH_CSC      
    FOLDERID_SEARCH_MAPI     
    FOLDERID_SearchHome      
    FOLDERID_SidebarDefaultParts
    FOLDERID_SidebarParts       
    FOLDERID_SyncManagerFolder
    FOLDERID_SyncResultsFolder
    FOLDERID_SyncSetupFolder  
    FOLDERID_UserPinned            
    FOLDERID_UserProfiles          
    FOLDERID_UserProgramFiles      
    FOLDERID_UserProgramFilesCommon
    FOLDERID_UsersFiles            
    FOLDERID_UsersLibraries        

    FOLDERID_VideosLibrary

    Thanks,

    Gerry

    Wednesday, January 02, 2013 8:32 PM
  • For an object to be accessible as an ActiveX (COM) automation object, it must implement the IDispatch interface. WSH-based scripts only support automation objects.

    IKnownFolder inherits from IUnknown, and I don't see any mention of it having an IDispatch interface. Thus, IKnownFolder would not be accessible from a VBScript WSH script.

    Bill

    • Marked as answer by Gerry Michaud Thursday, January 03, 2013 2:25 PM
    Wednesday, January 02, 2013 8:43 PM
  • Richard, jvr & Bill, thanks for the responses. I was hoping for a better answer, but I had a feeling the answer was gonna be "no".

    I should have asked this question here before spending hours researching and trying ... 'imaginative' code :-) but what the heck - it was fun.

    jvr, based on the knownfolderids I list above with no CSIDL equivalent, I have to disagree about all folders being equally exposed, but I can't say it will be a significant disadvantage not having a path to the 'new' folders (libraries). As I said, I mostly wanted to see what was available to be exploited. Having said that, there is a real need to get the true language specific path to these folders. Hardcoding english paths is probably a bad idea. Retrieving them programmatically is best, as I'm sure you all know.

    Since its the end of the day and I'm in a rambling mood, I'll ramble on... What started me down this road was the need to get the x86 programfiles folder on any OS 'bitness'. I read somewhere that the FOLDERID_ProgramFilesX86 would return C:\Program Files on 32-bit OS and C:\Program Files (x86) on a 64-bit device. PERFECT! Less work for me!. Wrong! I have since read that this is not true, but regardless, that's the kind of thing I was after. The hint of a better way to get that folder path was tempting, so I did more research and found out more about these new knownfolders. It's a shame they are not exploitable from vbscript.

    RE: Migrating to powershell. I had asked about this a few years ago (when it would have been simpler) and was shot down. Management had some kind of (probably bogus) security concern. now it will be a multi-year effort to get it everywhere. I guess I have nothing better to do...

    Thanks again,

    Gerry

    Wednesday, January 02, 2013 9:19 PM
  • Hi,

    This is one of the reasons for stating your intended purpose(s) along with your exact question.

    You can use the WOW64 emulator environment variables to get the paths in question without IKnownFolder. See WOW64 Implementation Details for more information.

    Bill

    Wednesday, January 02, 2013 9:28 PM
  • Richard, jvr & Bill, thanks for the responses. I was hoping for a better answer, but I had a feeling the answer was gonna be "no".

    I should have asked this question here before spending hours researching and trying ... 'imaginative' code :-) but what the heck - it was fun.

    jvr, based on the knownfolderids I list above with no CSIDL equivalent, I have to disagree about all folders being equally exposed, but I can't say it will be a significant disadvantage not having a path to the 'new' folders (libraries). As I said, I mostly wanted to see what was available to be exploited. Having said that, there is a real need to get the true language specific path to these folders. Hardcoding english paths is probably a bad idea. Retrieving them programmatically is best, as I'm sure you all know.

    Since its the end of the day and I'm in a rambling mood, I'll ramble on... What started me down this road was the need to get the x86 programfiles folder on any OS 'bitness'. I read somewhere that the FOLDERID_ProgramFilesX86 would return C:\Program Files on 32-bit OS and C:\Program Files (x86) on a 64-bit device. PERFECT! Less work for me!. Wrong! I have since read that this is not true, but regardless, that's the kind of thing I was after. The hint of a better way to get that folder path was tempting, so I did more research and found out more about these new knownfolders. It's a shame they are not exploitable from vbscript.

    RE: Migrating to powershell. I had asked about this a few years ago (when it would have been simpler) and was shot down. Management had some kind of (probably bogus) security concern. now it will be a multi-year effort to get it everywhere. I guess I have nothing better to do...

    Thanks again,

    Gerry

    First detect architecture then make appropriate call.  All KnownIDs are map[ped to CISDL and KNOWNID buys you nothing on any system.

    CSIDL_PROGRAM_FILES
    FOLDERID_ProgramFiles

    Version 5.0. The Program Files folder. A typical path is C:\Program Files.

    CSIDL_PROGRAM_FILESX86
    FOLDERID_ProgramFilesX86

    Happy New Year ¯\_(ツ)_/¯

    • Proposed as answer by jrv Thursday, January 03, 2013 2:10 AM
    • Unproposed as answer by jrv Thursday, January 03, 2013 2:10 AM
    Wednesday, January 02, 2013 10:55 PM
  • First detect architecture then make appropriate call.  All KnownIDs are map[ped to CISDL and KNOWNID buys you nothing on any system.

    (?) I think the question has already been answered, hasn't it?

    Bill

    Wednesday, January 02, 2013 11:18 PM
  • I just test for the existence of the folder "Program Files (x86)" if I need it. In a related area, reading from the registry, I use code similar to below to access the 32-bit portion whether the OS is 32-bit or 64-bit:

    Option Explicit

    Dim objNetwork, strComputer, objContext, objLocator, objServices
    Dim objReg, objInParams, objOutParams, strValue

    Const HKEY_LOCAL_MACHINE = &H80000002

    ' Retrieve local machine name.
    Set objNetwork = CreateObject("Wscript.Network")
    strComputer = objNetwork.ComputerName

    ' This code reads the 32-bit section of the registry whether the
    ' OS is 32-bit or 64-bit.
    Set objContext = CreateObject("WbemScripting.SWbemNamedValueSet")
    objContext.Add "__ProviderArchitecture", 32
    objContext.Add "__RequiredArchitecture", True
    Set objLocator = CreateObject("WbemScripting.SWbemLocator")
    Set objServices = objLocator.ConnectServer(strComputer, _
        "root\default", "", "", , , , objContext)
    Set objReg = objServices.Get("StdRegProv")

    Set objInParams = objReg.Methods_("GetStringValue").Inparameters
    objInParams.HdefKey = HKEY_LOCAL_MACHINE
    objInParams.Ssubkeyname = "Software\My Company\My Application"
    objInParams.Svaluename = "MyKey"
    Set objOutParams = objReg.ExecMethod_("GetStringValue", _
        objInParams, , objContext)
    strValue = objOutParams.SValue & ""
    Wscript.Echo "Key value: " & strValue

    -----



    Richard Mueller - MVP Directory Services

    Wednesday, January 02, 2013 11:45 PM
  • Richard, you have some interesting code that I've never seen before, like using .Inparameters. Always good to learn something new. Thanks!

    I've marked this question as answered. No, I can't use KnownFolderIDs from vbscript. That was my question.

    Thanks to all who offered input.

    Gerry.

    Thursday, January 03, 2013 2:33 PM