Announcement

Collapse
No announcement yet.

Creating a folder on the desktop and putting files in it

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Creating a folder on the desktop and putting files in it

    I have read the Database extesivly on this subject. I have found the code below. When I execute it I get "desktop" as the Answer.

    when I then try to MKDIR nothing happens, and obviously the file is not copied.

    I can get my setup.exe to do everything else fine.

    (Code courtesy of Semen - thx semen your code allways works)
    Code:
    #COMPILE EXE
    #REGISTER NONE
    #DIM ALL
    #INCLUDE "Win32Api.Inc"
    
    '===============================================================================================
    DECLARE FUNCTION COMCall1 (p1 AS ANY) AS DWORD
    DECLARE FUNCTION COMCall2 (p1 AS ANY, p2 AS ANY) AS DWORD
    DECLARE FUNCTION COMCall3 (p1 AS ANY, p2 AS ANY, p3 AS ANY) AS DWORD
    DECLARE FUNCTION COMCall4 (p1 AS ANY, p2 AS ANY, p3 AS ANY, p4 AS ANY) AS DWORD
    DECLARE FUNCTION COMCall5 (p1 AS ANY, p2 AS ANY, p3 AS ANY, p4 AS ANY, p5 AS ANY) AS DWORD
    '==================================== iMalloc ================================
    ' // *** IUnknown methods ***
    %iMalloc_QueryInterface = 0
    %iMalloc_AddRef = 4
    %iMalloc_Release = 8
    ' // *** IMalloc methods ***
    %iMalloc_Alloc = 12
    %iMalloc_Realloc = 16
    %iMalloc_Free = 20
    %iMalloc_GetSize = 24
    %iMalloc_DidAlloc = 28
    %iMalloc_HeapMinimize = 32
    '==================================== iShellFolder ================================
    ' // *** IUnknown methods ***
    %iShellFolder_QueryInterface = 0
    %iShellFolder_AddRef = 4
    %iShellFolder_Release = 8
    ' // *** IShellFolder methods ***
    %iShellFolder_ParseDisplayName = 12
    %iShellFolder_EnumObjects = 16
    %iShellFolder_BindToObject = 20
    %iShellFolder_BindToStorage = 24
    %iShellFolder_CompareIDs = 28
    %iShellFolder_CreateViewObject = 32
    %iShellFolder_GetAttributesOf = 36
    %iShellFolder_GetUIObjectOf = 40
    %iShellFolder_GetDisplayNameOf = 44
    %iShellFolder_SetNameOf = 48
    
    %SHGDN_NORMAL = &H0000& ' // Default (display purpose)
    %SHGDN_INFOLDER = &H0001& ' // displayed under a folder (relative)
    %SHGDN_INCLUDE_NONFILESYS = &H2000& ' // If Not Set, display names For Shell Name space items that are Not In the file system will fail.
    %SHGDN_FORADDRESSBAR = &H4000& ' // For displaying In the address (drives dropdown) Bar
    %SHGDN_FORPARSING = &H8000& ' // For ParseDisplayName Or path
    
    %STRRET_WSTR = 0&
    %STRRET_OFFSET = 1&
    %STRRET_CSTR = 2&
    
    UNION STRRETUNION
    pOleStr AS BYTE PTR ' // must be freed by caller of GetDisplayNameOf
    pStr AS DWORD ' // Not USED
    uOffset AS DWORD ' // Offset into ****EMID
    cStr AS ASCIIZ * %MAX_PATH ' // Buffer To fill In (ANSI)
    END UNION
    
    TYPE STRRET
    uType AS DWORD
    Dummy AS STRRETUNION
    END TYPE
    
    DECLARE FUNCTION SHGetMalloc LIB "Shell32.Dll" ALIAS "SHGetMalloc" (pMalloc AS DWORD) AS LONG
    DECLARE FUNCTION SHGetDesktopFolder LIB "Shell32.Dll" ALIAS "SHGetDesktopFolder" (ppshf AS ANY) AS LONG
    
    GLOBAL Answer AS STRING
    
    '=========================================================================================
    SUB PrintStrRet(pMalloc AS DWORD PTR, pidl AS DWORD, lpStr AS STRRET)
    DIM lpOleStr AS DWORD
    DIM lpsz AS ASCIIZ PTR
    DIM cch AS DWORD
    DIM pp AS DWORD PTR, lResult AS DWORD
    SELECT CASE (lpStr.uType)
    ' The 1st UINT (Long) of the array points to a Unicode
    ' str which must be freed (WinNT only).
    CASE %STRRET_WSTR:
    ' Get the strings len
    cch = WideCharToMultiByte(%CP_ACP, %Null, _
    BYVAL lpStr.Dummy.pOleStr, -1&, BYVAL 0&, 0&, BYVAL %Null, 0&)
    pp = @pMalloc + %iMalloc_Alloc
    CALL DWORD @pp USING COMCall2 (BYVAL pMalloc, BYVAL cch) TO lpsz
    IF (lpsz <> 0) THEN
    ' Map the Unicode str to ANSII using the ptrs
    WideCharToMultiByte %CP_ACP, %Null, _
    BYVAL lpStr.Dummy.pOleStr, -1&, BYVAL lpsz, _
    cch, BYVAL %Null, 0&
    Answer = Answer + @lpsz + "\"' + $CRLF ' <------------
    pp = @pMalloc + %iMalloc_Free
    CALL DWORD @pp USING COMCall2 _
    (BYVAL pMalloc, BYVAL lpsz) TO lResult
    END IF
    
    ' The 1st UINT (Long) of the array points to the location
    ' (uOffset bytes) to the ANSII str in the pidl
    CASE %STRRET_OFFSET:
    lpsz = pidl + lpStr.Dummy.uOffSet
    Answer = Answer + @lpsz + "\"' + $CRLF ' <------------
    ' The display name is returned in cStr
    CASE %STRRET_CSTR:
    Answer = Answer + lpStr.Dummy.cStr + "\" '+ $CRLF ' <------------
    END SELECT
    END SUB
    
    '=========================================================================================
    FUNCTION CopyItemID(pMalloc AS DWORD PTR, pidl AS DWORD) AS DWORD
    DIM cb AS INTEGER, iZero AS INTEGER, pp AS DWORD PTR
    ' Get the size of the specified item identifier.
    MoveMemory BYREF cb, BYVAL pidl, 2
    ' Allocate a new item identifier list.
    DIM pidlNew AS DWORD
    pp = @pMalloc + %iMalloc_Alloc
    CALL DWORD @pp USING COMCall2 _
    (BYVAL pMalloc, BYVAL (cb + 2)) TO pidlNew
    IF (pidlNew = 0) THEN FUNCTION = 0: EXIT FUNCTION
    ' Copy the specified item identifier.
    MoveMemory BYVAL pidlNew, BYVAL pidl, cb
    ' Append a terminating zero.
    MoveMemory BYVAL pidlNew + cb, BYREF iZero, 2
    FUNCTION = pidlNew
    END FUNCTION
    
    '=========================================================================================
    FUNCTION GetNextItemID(pidl AS DWORD) AS DWORD
    DIM cb AS INTEGER
    ' Get the size of the specified item identifier.
    MoveMemory BYREF cb, BYVAL pidl, 2
    ' If the size is zero, it is the end of the list.
    IF (cb = 0) THEN FUNCTION = 0: EXIT FUNCTION
    ' Add cb to pidl (casting to increment by bytes).
    pidl = pidl + cb
    ' Return NULL if it is null-terminating or a pidl otherwise.
    MoveMemory BYREF cb, BYVAL pidl, 2
    IF cb THEN FUNCTION = pidl
    END FUNCTION
    
    '=========================================================================================
    FUNCTION DisplayPIDL(CSIDL AS LONG) AS LONG
    DIM pMalloc AS DWORD PTR
    DIM pidlPrograms AS DWORD
    DIM pFolder AS DWORD PTR
    DIM isfFolder AS DWORD PTR
    DIM IID_IShellFolder AS STRING * 16
    Answer = "" ' <----------------
    ' Fill IShellFolder Interface ID, {000214E6-0000-0000-C000-000000046}
    IID_IShellFolder = MKL$(&H000214E6) + CHR$(0, 0, 0, 0, &HC0, 0, 0, 0, 0, 0, 0, &H46)
    
    ' Get the shell's allocator.
    IF SHGetMalloc(pMalloc) THEN FUNCTION = 1: EXIT FUNCTION
    
    ' Get the PIDL for the Programs folder.
    IF SHGetSpecialFolderLocation(%HWND_DESKTOP, CSIDL, BYVAL VARPTR(pidlPrograms)) THEN
    FUNCTION = 1: EXIT FUNCTION
    ELSE ' Start with the desktop folder (we're bound to it)
    IF ISFALSE(SHGetDesktopFolder(pFolder)) THEN
    isfFolder = pFolder ' Set isfFolder = pFolder
    
    DIM pidl AS DWORD
    
    ' Process each item identifier in the list.
    pidl = pidlPrograms
    WHILE pidl
    DIM sName AS STRRET
    DIM pSubFolder AS DWORD PTR
    DIM pidlCopy AS DWORD
    
    ' Copy the item identifier to a list by itself.
    pidlCopy = CopyItemID(BYVAL pMalloc, pidl)
    IF pidlCopy = 0 THEN EXIT DO
    
    ' Display the name of the subfolder.
    DIM pp AS DWORD PTR, lResult AS DWORD
    pp = @isfFolder + %iShellFolder_GetDisplayNameOf
    CALL DWORD @pp USING COMCall4 _
    (BYVAL isfFolder, BYVAL pidlCopy, BYVAL %SHGDN_INFOLDER, sName) TO lResult
    IF lResult = 0 THEN PrintStrRet BYVAL pMalloc, pidlCopy, sName
    ' Bind to the subfolder.
    pp = @isfFolder + %iShellFolder_BindToObject
    
    CALL DWORD @pp USING COMCall5 _
    (BYVAL isfFolder, BYVAL pidlCopy, _
    BYVAL %Null, BYREF IID_IShellFolder, pSubFolder) TO lResult
    IF lResult THEN
    pp = @pMalloc + %iMalloc_Free
    CALL DWORD @pp USING COMCall2 _
    (BYVAL pMalloc, BYVAL pidlCopy) TO lResult
    EXIT DO
    END IF
    ' Free the copy of the item identifier.
    pp = @pMalloc + %iMalloc_Free
    CALL DWORD @pp USING COMCall2 _
    (BYVAL pMalloc, BYVAL pidlCopy) TO lResult
    ' Release the parent folder and point to the subfolder.
    isfFolder = pSubFolder ' Set isfFolder = pSubFolder
    ' Get the next item ID
    pidl = GetNextItemID(pidl) ' (was in the c for statement at top)
    LOOP
    END IF
    ' Free the PIDL for the Programs folder.
    pp = @pMalloc + %iMalloc_Free
    CALL DWORD @pp USING COMCall2 _
    (BYVAL pMalloc, BYVAL pidlPrograms) TO lResult
    END IF
    FUNCTION = 0
    END FUNCTION
    
    '=========================================================================================
    FUNCTION PBMAIN
    LOCAL  TargetFile AS STRING, DestFolder AS STRING, DesktopFolder AS STRING
    'DisplayPIDL %CSIDL_PROGRAMS: MSGBOX Answer, , "%CSIDL_PROGRAMS"
    'DisplayPIDL %CSIDL_STARTUP : MSGBOX Answer, , "%CSIDL_STARTUP"
    'DisplayPIDL %CSIDL_FONTS : MSGBOX Answer, , "%CSIDL_FONTS"
    DisplayPIDL %CSIDL_desktop : MSGBOX Answer, , "%CSIDL_desktop"
        TargetFile = "key.ini"
        DestFolder = "Desktop\MyNewFolder\"
        MKDIR DestFolder
        FILECOPY TargetFile, DestFolder+TargetFile
    END FUNCTION
    ------------------
    Kind Regards
    Mike

  • #2
    "Desktop\MyNewFolder\" is not a valid path. Best to use full path,
    like MKDIR "c:\Windows\Desktop\MyNewFolder".."

    Important to remember: The Desktop folder is only called that in
    English versions of Windows. Other languages - other names. Have
    seen several US app's that has failed to be properly installed
    because of this, because they have hardcoded the name, and my
    Desktop is called "Skrivbord" (Swedish for desktop). So, always
    use the result of the SHGetDesktopFolder call instead.


    ------------------

    Comment


    • #3
      THx so much Borje, that makes sense now!

      ------------------
      Kind Regards
      Mike

      Comment

      Working...
      X