SuperviseDirectory() & GetKnownFolder() [Module][WIN]

Share your advanced PureBasic knowledge/code with the community.
User avatar
Bisonte
Addict
Addict
Posts: 1232
Joined: Tue Oct 09, 2007 2:15 am

SuperviseDirectory() & GetKnownFolder() [Module][WIN]

Post by Bisonte »

Hello.

I needed for a project a monitoring of a system directory of Windows and
found a code from Sparkie in the WINAPI library of RSBasic. This one was too inflexible for me,
so I generalized it a little bit and put it in a module.

While using it I noticed a nasty carver from Sparkie, who took care of the filename,
which were longer than the previous name, influenced the newly read out name (it was always used
the maximum length).

IMPORTANT!!! is only that, when querying an event, the memory whose address can be called with EventData ()
(the filename is in it) will be released. (See demo at the end of the code)

Since my beloved procedure "GetSpecialFolder (CLSID)" from TS-Soft cannot find all directories anymore,
I extended the procedure "GetKnownFolder ()" of GS-68 a little bit, so that you can get constants instead of addresses.
to determine a system directory path. This is then processed in PB manner with a final backslash
is output.
Microsoft means that this is now up to date and the CLSID method is obsolete since Windows 8..... You know how it is.

The name of the module is completely unimportant..... I was concerned with little typing :mrgreen:

History :
  • 05.08.18 - V1.06
  • Bugfix : Sometimes StopSuperViseDirectory() don't work correct.
  • 10.03.18 - V1.05
  • Bugfix : FilenameLength was unmodified, so sometimes the string was longer than it should.
  • 09.03.18 - V1.04
  • To identify the supervised directory, StartSuperViseDirectory() returns an ID, that you can use with :
  • GetSuperViseDirectory(ID) returns the supervised directory
  • 09.03.18 - V1.03
  • Renaming files where also detected if the eventtype is given as parameter at the Init_SuperVisorDirectory() call..
  • To get both filenames I use StringField with ":" as delimeter
  • First Field = Old Filename , Second Field = New FileName
  • 09.03.18 : V1.02
  • Recursivity is optinional on/off switchable
  • 08.03.18 : V1.01
  • Clear the entire buffer in the thread now.
  • 08.03.18 : V1.00
  • Release
Long speech short code... (if you don't count the data lines ;) )

Code: Select all

DeclareModule mAPI
   
  ; mAPI V1.06
  ; Bugfix : StopSuperViseDirectory()
  
  ; mApi V1.05
  ; Bugfix : FilenameLength was unmodified, so sometimes the string was longer than it should.
 
  ; mApi V1.04
  ; Now returns StartSuperVise an ID. This ID is present in EventGadget() at every Event.
  ; GetSuperViseDirectory(ID) returns the Directory that is supervised with this ID.
 
  ; mAPI V1.03
  ; Renaming files where also detected if the eventtype is given as parameter at
  ; Init_SuperVisorDirectory() call.
  ; to get both filenames I use StringField with ":" as delimeter
  ; First Field = Old Filename , Second Field = New FileName
 
  ; mAPI V1.02
  ; Supervise SubDirectories recursiv is now an optional parameter.
 
  ; mAPI V1.01
  ; Clear buffer completly in loop of thread.
 
  ; mAPI V1.00
  ; Release
 
  ; GetKnownFolderPath()
  ; Original Author : GJ-68
  ; Original Link   : http://www.purebasic.fr/english/viewtopic.php?p=416385#p416385
  ; modified by George Bisonte (Module & "Constants : source MSDN" )
 
  ; SuperVisorDirectory()
  ; Original Author: Sparkie
  ; Original Link  : http://www.purebasic.fr/english/viewtopic.php?p=86514#p86514
  ; modified by George Bisonte for PB 5.62 (EventDriven & Module)
 
  EnableExplicit

  Enumeration 0
    #FID_NetworkFolder
    #FID_ComputerFolder
    #FID_InternetFolder
    #FID_ControlPanelFolder
    #FID_PrintersFolder
    #FID_SyncManagerFolder
    #FID_SyncSetupFolder
    #FID_ConflictFolder
    #FID_SyncResultsFolder
    #FID_RecycleBinFolder
    #FID_ConnectionsFolder
    #FID_Fonts
    #FID_Desktop
    #FID_Startup
    #FID_Programs
    #FID_StartMenu
    #FID_Recent
    #FID_SendTo
    #FID_Documents
    #FID_Favorites
    #FID_NetHood
    #FID_PrintHood
    #FID_Templates
    #FID_CommonStartup
    #FID_CommonPrograms
    #FID_CommonStartMenu
    #FID_PublicDesktop
    #FID_ProgramData
    #FID_CommonTemplates
    #FID_PublicDocuments
    #FID_RoamingAppData
    #FID_LocalAppData
    #FID_LocalAppDataLow
    #FID_InternetCache
    #FID_Cookies
    #FID_History
    #FID_System
    #FID_SystemX86
    #FID_Windows
    #FID_Profile
    #FID_Pictures
    #FID_ProgramFilesX86
    #FID_ProgramFilesCommonX86
    #FID_ProgramFilesX64
    #FID_ProgramFilesCommonX64
    #FID_ProgramFiles
    #FID_ProgramFilesCommon
    #FID_UserProgramFiles
    #FID_UserProgramFilesCommon
    #FID_AdminTools
    #FID_CommonAdminTools
    #FID_Music
    #FID_Videos
    #FID_Ringtones
    #FID_PublicPictures
    #FID_PublicMusic
    #FID_PublicVideos
    #FID_PublicRingtones
    #FID_ResourceDir
    #FID_LocalizedResourcesDir
    #FID_CommonOEMLinks
    #FID_CDBurning
    #FID_UserProfiles
    #FID_Playlists
    #FID_SamplePlaylists
    #FID_SampleMusic
    #FID_SamplePictures
    #FID_SampleVideos
    #FID_PhotoAlbums
    #FID_Public
    #FID_ChangeRemovePrograms
    #FID_AppUpdates
    #FID_AddNewPrograms
    #FID_Downloads
    #FID_PublicDownloads
    #FID_SavedSearches
    #FID_QuickLaunch
    #FID_Contacts
    #FID_PublicGameTasks
    #FID_GameTasks
    #FID_SavedGames
    #FID_Games
    #FID_SEARCH_MAPI
    #FID_SEARCH_CSC
    #FID_Links
    #FID_UsersFiles
    #FID_UsersLibraries
    #FID_SearchHome
    #FID_OriginalImages
    #FID_DocumentsLibrary
    #FID_MusicLibrary
    #FID_PicturesLibrary
    #FID_VideosLibrary
    #FID_RecordedTVLibrary
    #FID_HomeGroup
    #FID_DeviceMetadataStore
    #FID_Libraries
    #FID_PublicLibraries
    #FID_UserPinned
    #FID_ImplicitAppShortcuts
  EndEnumeration
   
  ; Get Windows-Systemfolder by FID Constant for compatibility => Windows 7 (MSDN)
  ; Returns full path with Backslash like PB functions
  Declare.s GetKnownFolderPath(FID)
 
  ; Supervise a folder with a thread and if changes PostEvent() : UNICODE Only!
  ; BE SURE THAT YOU FREE THE MEMORY (EventData() is the address) !!!!
 
  ; Declare Event and EventTypes for SuperVisorDirectory
  Declare.i Init_SuperVisorDirectory(Event, EventTypeAdd, EventTypeModified, EventTypeRemove, EventTypeRename = 0)
  ; Start SuperVisor Thread, Returns SuperViser ID
  Declare.i StartSuperviseDirectory(Directory.s, Window, Recursive = #True)                                     
  ; Stop SuperVisorThread
  Declare.i StopSuperviseDirectory(Directory.s)                                               
  ; Get the Directory from a SuperViser ID
  Declare.s GetSuperViserDirectory(ID)
EndDeclareModule
Module mAPI
 
  #Magic = 2018030922
 
  #FILE_NOTIFY_CHANGE_LAST_ACCESS = $20
  #FILE_NOTIFY_CHANGE_CREATION    = $40
  #FILE_NOTIFY_CHANGE_ALL         = $17F
  #FILE_ACTION_ADDED              = 1
  #FILE_ACTION_REMOVED            = 2
  #FILE_ACTION_MODIFIED           = 3
  #FILE_ACTION_RENAMED_OLD_NAME   = 4
  #FILE_ACTION_RENAMED_NEW_NAME   = 5
 
  Structure FILE_NOTIFY_INFORMATION
    NextEntryOffset.l
    Action.l
    FileNameLength.l
    Filename.s{1024*32}
  EndStructure
 
  Prototype SHGetKnownFolderPath__(rfid, dwFlags.l, hToken, *ppszPath)

  Import "kernel32.lib"
    ReadDirectoryChangesW(hDirectory, lpBuffer, nBufferLength, bWatchSubtree, dwNotifyFilter, lpBytesReturned, lpOverlapped, lpCompletionRoutine)
  EndImport
 
  Structure s_superviseDirectory
    Magic.l
    Address.i
    ID.i
    Halt.i   
    Directory.s
    Window.i
    Recursive.i
    New.s
    Old.s
  EndStructure
  Structure s_supervisorInit
    Init.i
    Event.i
    ETADD.i
    ETMOD.i
    ETREM.i
    ETRENAME.i
  EndStructure
 
  Global NewMap SuperVisor.s_superviseDirectory()
  Global SuperVisorInit.s_supervisorInit
 
  Procedure.s GetKnownFolderPath(FID)
   
    Protected DLL, i, Result.s, *UnicodeBuffer, kfFlag.l, SHGetKnownFolderPath.SHGetKnownFolderPath__
    Protected *FolderID
   
    If FID > -1 And FID <= #FID_ImplicitAppShortcuts
      *FolderID = ?FOLDERID_NetworkFolder + (16 * FID)
    Else
      ProcedureReturn ""
    EndIf
   
    DLL = OpenLibrary(#PB_Any, "Shell32.dll")
    If DLL
      SHGetKnownFolderPath = GetFunction(DLL, "SHGetKnownFolderPath")
      If SHGetKnownFolderPath
        If SHGetKnownFolderPath(*FolderID, kfFlag, #Null, @*UnicodeBuffer) = #S_OK And *UnicodeBuffer
          Result = PeekS(*UnicodeBuffer, -1, #PB_Unicode) + "\"
          CoTaskMemFree_(*UnicodeBuffer)
        EndIf
      EndIf
      CloseLibrary(DLL)
    EndIf
   
    If Result = ""
      Result = GetHomeDirectory()
    EndIf
   
    ProcedureReturn Result
   
  EndProcedure

  Procedure.i SuperVisorThread(*p.s_superviseDirectory)
   
    Protected NotifyFilter.l = #FILE_NOTIFY_CHANGE_ALL
    Protected buffer.FILE_NOTIFY_INFORMATION, ovlp.OVERLAPPED
    Protected hDir, bytesRead, *FileName, FileAction_File.s, String.s, Size1, Size2
   
    If *p
     
      hDir = CreateFile_(*p\Directory, #FILE_LIST_DIRECTORY, #FILE_SHARE_READ | #FILE_SHARE_WRITE | #FILE_SHARE_DELETE, #Null, #OPEN_EXISTING, #FILE_FLAG_BACKUP_SEMANTICS, #Null)
      
      
      While ReadDirectoryChangesW(hDir, @buffer, SizeOf(FILE_NOTIFY_INFORMATION), *p\Recursive, NotifyFilter, bytesRead, ovlp, 0)
               
        FileAction_File = PeekS(@buffer\Filename, buffer\FileNameLength / SizeOf(Unicode), #PB_Unicode)

        *FileName = AllocateMemory(StringByteLength(FileAction_File, #PB_Unicode) + StringByteLength(" ", #PB_Unicode))
        If *FileName
          PokeS(*FileName, FileAction_File, -1, #PB_Unicode)
         
          Select buffer\Action
            Case #FILE_ACTION_ADDED   
              PostEvent(SuperVisorInit\Event, *p\Window, *p\Address, SuperVisorInit\ETADD, *FileName)
            Case #FILE_ACTION_MODIFIED
              PostEvent(SuperVisorInit\Event, *p\Window, *p\Address, SuperVisorInit\ETMOD, *FileName)
            Case #FILE_ACTION_REMOVED
              PostEvent(SuperVisorInit\Event, *p\Window, *p\Address, SuperVisorInit\ETREM, *FileName)
            Case #FILE_ACTION_RENAMED_OLD_NAME
              If SuperVisorInit\ETRENAME
                *p\Old = FileAction_File : *p\New = PeekS(@buffer\Filename + buffer\NextEntryOffset, -1, #PB_Unicode)
              Else
                *p\Old = "" : *p\New = ""
              EndIf
             
            Default
              FreeMemory(*FileName)
             
          EndSelect
         
          If SuperVisorInit\ETRENAME
            If *p\New <> "" And *p\Old <> ""
              String = *p\Old + ":" + *p\New
              *FileName = AllocateMemory(StringByteLength(String, #PB_Unicode) + StringByteLength(" ", #PB_Unicode))
              If *FileName
                PokeS(*FileName, String, -1, #PB_Unicode)
                PostEvent(SuperVisorInit\Event, *p\Window, *p\Address, SuperVisorInit\ETRENAME, *FileName)
              EndIf 
            EndIf
            *p\Old = "" : *p\New = ""
          EndIf
         
        EndIf
        
       
        ; Clear buffer
        buffer\Filename = "" : buffer\Action = 0 : buffer\FileNameLength = 0 : buffer\NextEntryOffset = 0
        
        If *p\Halt = #True : Break : EndIf
        
      Wend
      
      
    EndIf     
   
  EndProcedure
 
  Procedure.i Init_SuperVisorDirectory(Event, EventTypeAdd, EventTypeModified, EventTypeRemove, EventTypeRename = 0)
   
    With SuperVisorInit
      \Init = #True
      \Event = Event
      \ETADD = EventTypeAdd
      \ETMOD = EventTypeModified
      \ETREM = EventTypeRemove
      \ETRENAME = EventTypeRename
    EndWith
       
  EndProcedure
 
  Procedure.i StopSuperviseDirectory(Directory.s)
    
    Protected Counter = 0
    
    If FindMapElement(SuperVisor(), LCase(Directory))
      If IsThread(SuperVisor()\ID)
        SuperVisor()\Halt = #True
        KillThread(SuperVisor()\ID)
      EndIf
      DeleteMapElement(SuperVisor(), LCase(Directory))
    EndIf
   
  EndProcedure
  Procedure.i StartSuperviseDirectory(Directory.s, Window, Recursive = #True)
   
    Protected Result = #False
   
    CompilerIf #PB_Compiler_Unicode = #False
      CompilerError "ONLY UNICODE"
    CompilerEndIf
         
    If SuperVisorInit\Init = #True And IsWindow(Window)
     
      If FindMapElement(SuperVisor(), LCase(Directory))
        If IsThread(SuperVisor()\ID)
          StopSuperviseDirectory(Directory)
        EndIf
      EndIf
     
      With SuperVisor(LCase(Directory))
        \Magic     = #Magic
        \Address   = @SuperVisor(LCase(Directory))
        \Recursive = Bool(Recursive)
        \Directory = Directory
        \Halt      = #False
        \Window    = Window
        \ID        = CreateThread(@SuperVisorThread(), @SuperVisor(LCase(Directory)))
      EndWith
     
      Result = SuperVisor(LCase(Directory))\Address
     
    Else
      Debug "You have to call Init_SuperVisorDirectory() first!"
    EndIf
   
    ProcedureReturn Result
   
  EndProcedure
 
  Procedure.s GetSuperViserDirectory(ID)
   
    Protected *a.s_superviseDirectory = ID
    Protected Result.s
   
    If *a
      If *a\Magic = #Magic
        Result = *a\Directory
      EndIf
    EndIf
   
    ProcedureReturn Result
           
  EndProcedure
   
  DataSection
    FOLDERID_NetworkFolder:
    Data.l $D20BEEC4
    Data.w $5CA8,$4905
    Data.b $AE,$3B,$BF,$25,$1E,$A0,$9B,$53
   
    FOLDERID_ComputerFolder:
    Data.l $0AC0837C
    Data.w $BBF8,$452A
    Data.b $85,$0D,$79,$D0,$8E,$66,$7C,$A7
   
    FOLDERID_InternetFolder:
    Data.l $4D9F7874
    Data.w $4E0C,$4904
    Data.b $96,$7B,$40,$B0,$D2,$0C,$3E,$4B
   
    FOLDERID_ControlPanelFolder:
    Data.l $82A74AEB
    Data.w $AEB4,$465C
    Data.b $A0,$14,$D0,$97,$EE,$34,$6D,$63
   
    FOLDERID_PrintersFolder:
    Data.l $76FC4E2D
    Data.w $D6AD,$4519
    Data.b $A6,$63,$37,$BD,$56,$06,$81,$85
   
    FOLDERID_SyncManagerFolder:
    Data.l $43668BF8
    Data.w $C14E,$49B2
    Data.b $97,$C9,$74,$77,$84,$D7,$84,$B7
   
    FOLDERID_SyncSetupFolder:
    Data.l $F214138
    Data.w $B1D3,$4A90
    Data.b $BB,$A9,$27,$CB,$C0,$C5,$38,$9A
   
    FOLDERID_ConflictFolder:
    Data.l $4BFEFB45
    Data.w $347D,$4006
    Data.b $A5,$BE,$AC,$0C,$B0,$56,$71,$92
   
    FOLDERID_SyncResultsFolder:
    Data.l $289A9A43
    Data.w $BE44,$4057
    Data.b $A4,$1B,$58,$7A,$76,$D7,$E7,$F9
   
    FOLDERID_RecycleBinFolder:
    Data.l $B7534046
    Data.w $3ECB,$4C18
    Data.b $BE,$4E,$64,$CD,$4C,$B7,$D6,$AC
   
    FOLDERID_ConnectionsFolder:
    Data.l $6F0CD92B
    Data.w $2E97,$45D1
    Data.b $88,$FF,$B0,$D1,$86,$B8,$DE,$DD
   
    FOLDERID_Fonts:
    Data.l $FD228CB7
    Data.w $AE11,$4AE3
    Data.b $86,$4C,$16,$F3,$91,$0A,$B8,$FE
   
    FOLDERID_Desktop:
    Data.l $B4BFCC3A
    Data.w $DB2C,$424C
    Data.b $B0,$29,$7F,$E9,$9A,$87,$C6,$41
   
    FOLDERID_Startup:
    Data.l $B97D20BB
    Data.w $F46A,$4C97
    Data.b $BA,$10,$5E,$36,$08,$43,$08,$54
   
    FOLDERID_Programs:
    Data.l $A77F5D77
    Data.w $2E2B,$44C3
    Data.b $A6,$A2,$AB,$A6,$01,$05,$4A,$51
   
    FOLDERID_StartMenu:
    Data.l $625B53C3
    Data.w $AB48,$4EC1
    Data.b $BA,$1F,$A1,$EF,$41,$46,$FC,$19
   
    FOLDERID_Recent:
    Data.l $AE50C081
    Data.w $EBD2,$438A
    Data.b $86,$55,$8A,$09,$2E,$34,$98,$7A
   
    FOLDERID_SendTo:
    Data.l $8983036C
    Data.w $27C0,$404B
    Data.b $8F,$08,$10,$2D,$10,$DC,$FD,$74
   
    FOLDERID_Documents:
    Data.l $FDD39AD0
    Data.w $238F,$46AF
    Data.b $AD,$B4,$6C,$85,$48,$03,$69,$C7
   
    FOLDERID_Favorites:
    Data.l $1777F761
    Data.w $68AD,$4D8A
    Data.b $87,$BD,$30,$B7,$59,$FA,$33,$DD
   
    FOLDERID_NetHood:
    Data.l $C5ABBF53
    Data.w $E17F,$4121
    Data.b $89,$00,$86,$62,$6F,$C2,$C9,$73
   
    FOLDERID_PrintHood:
    Data.l $9274BD8D
    Data.w $CFD1,$41C3
    Data.b $B3,$5E,$B1,$3F,$55,$A7,$58,$F4
   
    FOLDERID_Templates:
    Data.l $A63293E8
    Data.w $664E,$48DB
    Data.b $A0,$79,$DF,$75,$9E,$05,$09,$F7
   
    FOLDERID_CommonStartup:
    Data.l $82A5EA35
    Data.w $D9CD,$47C5
    Data.b $96,$29,$E1,$5D,$2F,$71,$4E,$6E
   
    FOLDERID_CommonPrograms:
    Data.l $0139D44E
    Data.w $6AFE,$49F2
    Data.b $86,$90,$3D,$AF,$CA,$E6,$FF,$B8
   
    FOLDERID_CommonStartMenu:
    Data.l $A4115719
    Data.w $D62E,$491D
    Data.b $AA,$7C,$E7,$4B,$8B,$E3,$B0,$67
   
    FOLDERID_PublicDesktop:
    Data.l $C4AA340D
    Data.w $F20F,$4863
    Data.b $AF,$EF,$F8,$7E,$F2,$E6,$BA,$25
   
    FOLDERID_ProgramData:
    Data.l $62AB5D82
    Data.w $FDC1,$4DC3
    Data.b $A9,$DD,$07,$0D,$1D,$49,$5D,$97
   
    FOLDERID_CommonTemplates:
    Data.l $B94237E7
    Data.w $57AC,$4347
    Data.b $91,$51,$B0,$8C,$6C,$32,$D1,$F7
   
    FOLDERID_PublicDocuments:
    Data.l $ED4824AF
    Data.w $DCE4,$45A8
    Data.b $81,$E2,$FC,$79,$65,$08,$36,$34
   
    FOLDERID_RoamingAppData:
    Data.l $3EB685DB
    Data.w $65F9,$4CF6
    Data.b $A0,$3A,$E3,$EF,$65,$72,$9F,$3D
   
    FOLDERID_LocalAppData:
    Data.l $F1B32785
    Data.w $6FBA,$4FCF
    Data.b $9D,$55,$7B,$8E,$7F,$15,$70,$91
   
    FOLDERID_LocalAppDataLow:
    Data.l $A520A1A4
    Data.w $1780,$4FF6
    Data.b $BD,$18,$16,$73,$43,$C5,$AF,$16
   
    FOLDERID_InternetCache:
    Data.l $352481E8
    Data.w $33BE,$4251
    Data.b $BA,$85,$60,$07,$CA,$ED,$CF,$9D
   
    FOLDERID_Cookies:
    Data.l $2B0F765D
    Data.w $C0E9,$4171
    Data.b $90,$8E,$08,$A6,$11,$B8,$4F,$F6
   
    FOLDERID_History:
    Data.l $D9DC8A3B
    Data.w $B784,$432E
    Data.b $A7,$81,$5A,$11,$30,$A7,$59,$63
   
    FOLDERID_System:
    Data.l $1AC14E77
    Data.w $02E7,$4E5D
    Data.b $B7,$44,$2E,$B1,$AE,$51,$98,$B7
   
    FOLDERID_SystemX86:
    Data.l $D65231B0
    Data.w $B2F1,$4857
    Data.b $A4,$CE,$A8,$E7,$C6,$EA,$7D,$27
   
    FOLDERID_Windows:
    Data.l $F38BF404
    Data.w $1D43,$42F2
    Data.b $93,$05,$67,$DE,$0B,$28,$FC,$23
   
    FOLDERID_Profile:
    Data.l $5E6C858F
    Data.w $0E22,$4760
    Data.b $9A,$FE,$EA,$33,$17,$B6,$71,$73
   
    FOLDERID_Pictures:
    Data.l $33E28130
    Data.w $4E1E,$4676
    Data.b $83,$5A,$98,$39,$5C,$3B,$C3,$BB
   
    FOLDERID_ProgramFilesX86:
    Data.l $7C5A40EF
    Data.w $A0FB,$4BFC
    Data.b $87,$4A,$C0,$F2,$E0,$B9,$FA,$8E
   
    FOLDERID_ProgramFilesCommonX86:
    Data.l $DE974D24
    Data.w $D9C6,$4D3E
    Data.b $BF,$91,$F4,$45,$51,$20,$B9,$17
   
    FOLDERID_ProgramFilesX64:
    Data.l $6D809377
    Data.w $6AF0,$444B
    Data.b $89,$57,$A3,$77,$3F,$02,$20,$0E
   
    FOLDERID_ProgramFilesCommonX64:
    Data.l $6365D5A7
    Data.w $F0D,$45E5
    Data.b $87,$F6,$D,$A5,$6B,$6A,$4F,$7D
   
    FOLDERID_ProgramFiles:
    Data.l $905E63B6
    Data.w $C1BF,$494E
    Data.b $B2,$9C,$65,$B7,$32,$D3,$D2,$1A
   
    FOLDERID_ProgramFilesCommon:
    Data.l $F7F1ED05
    Data.w $9F6D,$47A2
    Data.b $AA,$AE,$29,$D3,$17,$C6,$F0,$66
   
    FOLDERID_UserProgramFiles:
    Data.l $5CD7AEE2
    Data.w $2219,$4A67
    Data.b $B8,$5D,$6C,$9C,$E1,$56,$60,$CB
   
    FOLDERID_UserProgramFilesCommon:
    Data.l $BCBD3057
    Data.w $CA5C,$4622
    Data.b $B4,$2D,$BC,$56,$DB,$0A,$E5,$16
   
    FOLDERID_AdminTools:
    Data.l $724EF170
    Data.w $A42D,$4FEF
    Data.b $9F,$26,$B6,$0E,$84,$6F,$BA,$4F
   
    FOLDERID_CommonAdminTools:
    Data.l $D0384E7D
    Data.w $BAC3,$4797
    Data.b $8F,$14,$CB,$A2,$29,$B3,$92,$B5
   
    FOLDERID_Music:
    Data.l $4BD8D571
    Data.w $6D19,$48D3
    Data.b $BE,$97,$42,$22,$20,$08,$0E,$43
   
    FOLDERID_Videos:
    Data.l $18989B1D
    Data.w $99B5,$455B
    Data.b $84,$1C,$AB,$7C,$74,$E4,$DD,$FC
   
    FOLDERID_Ringtones:
    Data.l $C870044B
    Data.w $F49E,$4126
    Data.b $A9,$C3,$B5,$2A,$1F,$F4,$11,$E8
   
    FOLDERID_PublicPictures:
    Data.l $B6EBFB86
    Data.w $6907,$413C
    Data.b $9A,$F7,$4F,$C2,$AB,$F0,$7C,$C5
   
    FOLDERID_PublicMusic:
    Data.l $3214FAB5
    Data.w $9757,$4298
    Data.b $BB,$61,$92,$A9,$DE,$AA,$44,$FF
   
    FOLDERID_PublicVideos:
    Data.l $2400183A
    Data.w $6185,$49FB
    Data.b $A2,$D8,$4A,$39,$2A,$60,$2B,$A3
   
    FOLDERID_PublicRingtones:
    Data.l $E555AB60
    Data.w $153B,$4D17
    Data.b $9F,$04,$A5,$FE,$99,$FC,$15,$EC
   
    FOLDERID_ResourceDir:
    Data.l $8AD10C31
    Data.w $2ADB,$4296
    Data.b $A8,$F7,$E4,$70,$12,$32,$C9,$72
   
    FOLDERID_LocalizedResourcesDir:
    Data.l $2A00375E
    Data.w $224C,$49DE
    Data.b $B8,$D1,$44,$0D,$F7,$EF,$3D,$DC
   
    FOLDERID_CommonOEMLinks:
    Data.l $C1BAE2D0
    Data.w $10DF,$4334
    Data.b $BE,$DD,$7A,$A2,$0B,$22,$7A,$9D
   
    FOLDERID_CDBurning:
    Data.l $9E52AB10
    Data.w $F80D,$49DF
    Data.b $AC,$B8,$43,$30,$F5,$68,$78,$55
   
    FOLDERID_UserProfiles:
    Data.l $0762D272
    Data.w $C50A,$4BB0
    Data.b $A3,$82,$69,$7D,$CD,$72,$9B,$80
   
    FOLDERID_Playlists:
    Data.l $DE92C1C7
    Data.w $837F,$4F69
    Data.b $A3,$BB,$86,$E6,$31,$20,$4A,$23
   
    FOLDERID_SamplePlaylists:
    Data.l $15CA69B3
    Data.w $30EE,$49C1
    Data.b $AC,$E1,$6B,$5E,$C3,$72,$AF,$B5
   
    FOLDERID_SampleMusic:
    Data.l $B250C668
    Data.w $F57D,$4EE1
    Data.b $A6,$3C,$29,$0E,$E7,$D1,$AA,$1F
   
    FOLDERID_SamplePictures:
    Data.l $C4900540
    Data.w $2379,$4C75
    Data.b $84,$4B,$64,$E6,$FA,$F8,$71,$6B
   
    FOLDERID_SampleVideos:
    Data.l $859EAD94
    Data.w $2E85,$48AD
    Data.b $A7,$1A,$09,$69,$CB,$56,$A6,$CD
   
    FOLDERID_PhotoAlbums:
    Data.l $69D2CF90
    Data.w $FC33,$4FB7
    Data.b $9A,$0C,$EB,$B0,$F0,$FC,$B4,$3C
   
    FOLDERID_Public:
    Data.l $DFDF76A2
    Data.w $C82A,$4D63
    Data.b $90,$6A,$56,$44,$AC,$45,$73,$85
   
    FOLDERID_ChangeRemovePrograms:
    Data.l $DF7266AC
    Data.w $9274,$4867
    Data.b $8D,$55,$3B,$D6,$61,$DE,$87,$2D
   
    FOLDERID_AppUpdates:
    Data.l $A305CE99
    Data.w $F527,$492B
    Data.b $8B,$1A,$7E,$76,$FA,$98,$D6,$E4
   
    FOLDERID_AddNewPrograms:
    Data.l $DE61D971
    Data.w $5EBC,$4F02
    Data.b $A3,$A9,$6C,$82,$89,$5E,$5C,$04
   
    FOLDERID_Downloads:
    Data.l $374DE290
    Data.w $123F,$4565
    Data.b $91,$64,$39,$C4,$92,$5E,$46,$7B
   
    FOLDERID_PublicDownloads:
    Data.l $3D644C9B
    Data.w $1FB8,$4F30
    Data.b $9B,$45,$F6,$70,$23,$5F,$79,$C0
   
    FOLDERID_SavedSearches:
    Data.l $7D1D3A04
    Data.w $DEBB,$4115
    Data.b $95,$CF,$2F,$29,$DA,$29,$20,$DA
   
    FOLDERID_QuickLaunch:
    Data.l $52A4F021
    Data.w $7B75,$48A9
    Data.b $9F,$6B,$4B,$87,$A2,$10,$BC,$8F
   
    FOLDERID_Contacts:
    Data.l $56784854
    Data.w $C6CB,$462B
    Data.b $81,$69,$88,$E3,$50,$AC,$B8,$82
   
    FOLDERID_PublicGameTasks:
    Data.l $DEBF2536
    Data.w $E1A8,$4C59
    Data.b $B6,$A2,$41,$45,$86,$47,$6A,$EA
   
    FOLDERID_GameTasks:
    Data.l $54FAE61
    Data.w $4DD8,$4787
    Data.b $80,$B6,$9,$2,$20,$C4,$B7,$0
   
    FOLDERID_SavedGames:
    Data.l $4C5C32FF
    Data.w $BB9D,$43B0
    Data.b $B5,$B4,$2D,$72,$E5,$4E,$AA,$A4
   
    FOLDERID_Games:
    Data.l $CAC52C1A
    Data.w $B53D,$4EDC
    Data.b $92,$D7,$6B,$2E,$8A,$C1,$94,$34
   
    FOLDERID_SEARCH_MAPI:
    Data.l $98EC0E18
    Data.w $2098,$4D44
    Data.b $86,$44,$66,$97,$93,$15,$A2,$81
   
    FOLDERID_SEARCH_CSC:
    Data.l $EE32E446
    Data.w $31CA,$4ABA
    Data.b $81,$4F,$A5,$EB,$D2,$FD,$6D,$5E
   
    FOLDERID_Links:
    Data.l $BFB9D5E0
    Data.w $C6A9,$404C
    Data.b $B2,$B2,$AE,$6D,$B6,$AF,$49,$68
   
    FOLDERID_UsersFiles:
    Data.l $F3CE0F7C
    Data.w $4901,$4ACC
    Data.b $86,$48,$D5,$D4,$4B,$04,$EF,$8F
   
    FOLDERID_UsersLibraries:
    Data.l $A302545D
    Data.w $DEFF,$464B
    Data.b $AB,$E8,$61,$C8,$64,$8D,$93,$9B
   
    FOLDERID_SearchHome:
    Data.l $190337D1
    Data.w $B8CA,$4121
    Data.b $A6,$39,$6D,$47,$2D,$16,$97,$2A
   
    FOLDERID_OriginalImages:
    Data.l $2C36C0AA
    Data.w $5812,$4B87
    Data.b $BF,$D0,$4C,$D0,$DF,$B1,$9B,$39
   
    FOLDERID_DocumentsLibrary:
    Data.l $7B0DB17D
    Data.w $9CD2,$4A93
    Data.b $97,$33,$46,$CC,$89,$02,$2E,$7C
   
    FOLDERID_MusicLibrary:
    Data.l $2112AB0A
    Data.w $C86A,$4FFE
    Data.b $A3,$68,$D,$E9,$6E,$47,$1,$2E
   
    FOLDERID_PicturesLibrary:
    Data.l $A990AE9F
    Data.w $A03B,$4E80
    Data.b $94,$BC,$99,$12,$D7,$50,$41,$4
   
    FOLDERID_VideosLibrary:
    Data.l $491E922F
    Data.w $5643,$4AF4
    Data.b $A7,$EB,$4E,$7A,$13,$8D,$81,$74
   
    FOLDERID_RecordedTVLibrary:
    Data.l $1A6FDBA2
    Data.w $F42D,$4358
    Data.b $A7,$98,$B7,$4D,$74,$59,$26,$C5
   
    FOLDERID_HomeGroup:
    Data.l $52528A6B
    Data.w $B9E3,$4ADD
    Data.b $B6,$D,$58,$8C,$2D,$BA,$84,$2D
   
    FOLDERID_DeviceMetadataStore:
    Data.l $5CE4A5E9
    Data.w $E4EB,$479D
    Data.b $B8,$9F,$13,$0C,$02,$88,$61,$55
   
    FOLDERID_Libraries:
    Data.l $1B3EA5DC
    Data.w $B587,$4786
    Data.b $B4,$EF,$BD,$1D,$C3,$32,$AE,$AE
   
    FOLDERID_PublicLibraries:
    Data.l $48DAF80B
    Data.w $E6CF,$4F4E
    Data.b $B8,$00,$0E,$69,$D8,$4E,$E3,$84
   
    FOLDERID_UserPinned:
    Data.l $9E3995AB
    Data.w $1F9C,$4F13
    Data.b $B8,$27,$48,$B2,$4B,$6C,$71,$74
   
    FOLDERID_ImplicitAppShortcuts:
    Data.l $BCB5256F
    Data.w $79F6,$4CEE
    Data.b $B7,$25,$DC,$34,$E4,$2,$FD,$46
  EndDataSection
 
EndModule

; Demo

CompilerIf #PB_Compiler_IsMainFile
  
  EnableExplicit
  
  UseModule mAPI
  
  Enumeration #PB_Event_FirstCustomValue
    #WatchDir
  EndEnumeration
  Enumeration #PB_EventType_FirstCustomValue
    #WatchDir_Add
    #WatchDir_Mod
    #WatchDir_Del
    #WatchDir_Rename
  EndEnumeration
  
  ; Show SaveGame Directory Path
  Debug GetKnownFolderPath(#FID_SavedGames)
  
  ; Show Documents Directory Path
  Debug GetKnownFolderPath(#FID_Documents)
  
  ; Set your EventProcedure
  Procedure.i Event_WatchDir()
    
    Protected FileName.s, NewFile.s, OldFile.s
    
    If EventData()
      
      FileName = PeekS(EventData(), -1, #PB_Unicode)
      
      Select EventType()
        Case #WatchDir_Add
          Debug "File " + FileName + " was created in Directory " + GetSuperViserDirectory(EventGadget())
        Case #WatchDir_Mod
          Debug "File " + FileName + " was modified"
        Case #WatchDir_Del
          Debug "File " + FileName + " has been deleted"
        Case #WatchDir_Rename
          OldFile.s = StringField(FileName, 1, ":")
          NewFile.s = StringField(FileName, 2, ":")
          Debug "The File : " + OldFile + " was renamed to " + NewFile
      EndSelect
      
      ; Be sure, that you free the Memory !!! EventData contains an allocated memory block
      FreeMemory(EventData())
      
    EndIf
    
  EndProcedure
    
  ; Set your Event and the EventTypes
  Init_SuperVisorDirectory(#WatchDir, #WatchDir_Add, #WatchDir_Mod, #WatchDir_Del, #WatchDir_Rename)
  
  ; Open a window
  OpenWindow(0, 0, 0, 320, 200, "Test", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  
  ; Bind the Event 
  BindEvent(#WatchDir, @Event_WatchDir(), 0)
  
  ; Start SuperVisorDirectory
  StartSuperviseDirectory("C:\", 0, #False)
  StartSuperviseDirectory("E:\", 0, #False)
  
  ; Eventloop
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow 
  
  ; Stop SuperVisorDirectory
  StopSuperviseDirectory("C:\")
  StopSuperviseDirectory("E:\")

CompilerEndIf
Suggestions for improvement? Post it!

Edit : This thread is also present at the german forum.

Translated with http://www.DeepL.com/Translator
Last edited by Bisonte on Sun Aug 05, 2018 11:12 am, edited 4 times in total.
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
English is not my native language... (I often use DeepL to translate my texts.)
User avatar
Bisonte
Addict
Addict
Posts: 1232
Joined: Tue Oct 09, 2007 2:15 am

Re: SuperviseDirectory() & GetKnownFolder() [Module][WIN]

Post by Bisonte »

History wrote:V1.02 - ADD - Recursivity is optinional on/off switchable
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
English is not my native language... (I often use DeepL to translate my texts.)
User avatar
RSBasic
Moderator
Moderator
Posts: 1218
Joined: Thu Dec 31, 2009 11:05 pm
Location: Gernsbach (Germany)
Contact:

Re: SuperviseDirectory() & GetKnownFolder() [Module][WIN]

Post by RSBasic »

Great Image
Image
Image
User avatar
skywalk
Addict
Addict
Posts: 3996
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: SuperviseDirectory() & GetKnownFolder() [Module][WIN]

Post by skywalk »

Very useful 8)
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
Bisonte
Addict
Addict
Posts: 1232
Joined: Tue Oct 09, 2007 2:15 am

Re: SuperviseDirectory() & GetKnownFolder() [Module][WIN]

Post by Bisonte »

History wrote: 09.03.18 - V1.03 - ADD & FIX

Renaming files where also detected if the eventtype is given as parameter at the
Init_SuperVisorDirectory() call.
To get both filenames I use StringField with ":" as delimeter
First Field = Old Filename , Second Field = New FileName

Fix a memory leak if no action is executed at thread
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
English is not my native language... (I often use DeepL to translate my texts.)
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5353
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: SuperviseDirectory() & GetKnownFolder() [Module][WIN]

Post by Kwai chang caine »

Waaaooouuuhh !!!! :shock:
Very nice , and works perfectly here, under W10 X64
I have even run, two StartSuperviseDirectory in the same time for C and D, and perfect.
Perhaps adding the drive in the debug for know what drive is changed :wink:
Thanks a lot for this splendid sharing 8)
ImageThe happiness is a road...
Not a destination
User avatar
Bisonte
Addict
Addict
Posts: 1232
Joined: Tue Oct 09, 2007 2:15 am

Re: SuperviseDirectory() & GetKnownFolder() [Module][WIN]

Post by Bisonte »

ah I forgot to update at this forum ;)
Now it's done. V1.05 is online.
With Bugfix and identify the supervised directory.
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
English is not my native language... (I often use DeepL to translate my texts.)
User avatar
Bisonte
Addict
Addict
Posts: 1232
Joined: Tue Oct 09, 2007 2:15 am

Re: SuperviseDirectory() & GetKnownFolder() [Module][WIN]

Post by Bisonte »

Update :
  • 05.08.18 - V1.06
  • Bugfix : Sometimes StopSuperViseDirectory() don't work correct.
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
English is not my native language... (I often use DeepL to translate my texts.)
Post Reply