Announcement

Collapse
No announcement yet.

How to create shortcut in Vista?

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

  • How to create shortcut in Vista?

    I guess due to enhanced security restrictions Vista does not allow my program to create shortcut neither in the C:\Documents and Settings\All Users\Start Menu\Programs\Startup nor in the C:\Documents and Settings\All Users\Desktop folder. Is any workaround? What is allowed for creating shortcuts? What are the pre-requisites? Does it need administrator privileges?
    I do not have Vista, so any help will be highly appreciated.

    Thanks,

    Peter Redei

  • #2
    Upgrade and Vista

    This is just another reason to wait for Microsoft's next OS offering. Vista and upgrade is an oxymoron.

    Comment


    • #3
      Peter,

      Under Vista, those folders have differents names,
      for example, it may look like the following:

      CSIDL_COMMON_STARTUP = C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\
      CSIDL_COMMON_DESKTOPDIRECTORY = C:\Users\Public\Desktop\

      Also, privilege elevation under UAP seem's needed, see...
      http://www.powerbasic.com/support/fo...ML/014458.html

      Here is some code to, at least, get them...


      Code:
      #COMPILE EXE '#Win 8.04#
      #DIM ALL
      #REGISTER NONE
      #INCLUDE "Win32Api.Inc" '#2005-01-27#
      '______________________________________________________________________________
       
      FUNCTION FolderGet(CSIDL AS DWORD) AS STRING
       LOCAL pItemIdList AS ITEMIDLIST POINTER
       LOCAL zBuffer     AS ASCIIZ * %MAX_PATH + 1
       
       IF SHGetSpecialFolderLocation(BYVAL %HWND_DESKTOP, BYVAL CSIDL, pItemIdList) = %NO_ERROR THEN
        SHGetPathFromIDList BYVAL pItemIdList, zBuffer 'Returns TRUE if successful
        CoTaskMemFree BYVAL pItemIdList
        FUNCTION = zBuffer
       END IF
       
      END FUNCTION
      '______________________________________________________________________________
       
      FUNCTION PBMAIN
       LOCAL sBuffer AS STRING
       
       sBuffer = sBuffer & "%CSIDL_COMMON_STARTUP = " & FolderGet(%CSIDL_COMMON_STARTUP) & $CRLF & $CRLF
       
       sBuffer = sBuffer & "%CSIDL_COMMON_DESKTOPDIRECTORY = " & FolderGet(%CSIDL_COMMON_DESKTOPDIRECTORY) & $CRLF
       
       ? sBuffer
       
      END FUNCTION
      '______________________________________________________________________________
      '
      Last edited by Pierre Bellisle; 17 Apr 2021, 10:56 PM.

      Comment


      • #4
        Thank you Pierre, but my problem is not the coding, I know how to retrieve from a CSIDL constant the path to the location. This is exactly what my program is doing. Nothing is hard-coded and the program works well in any Windows operating system but Vista. Since I have no Vista I cannot go forward here myself. The question is that Vista security might blocks the creation of a shortcut in some folders? I assumed it does so I wrote the following code that I thought will allow access:
        Code:
        #IF NOT %DEF(%ACLAPI)
            #INCLUDE "ACLAPI.inc"
        #ENDIF
        
        FUNCTION GiveDirectoryUserFullAccess(lpPath AS ASCIIZ) AS LONG
            LOCAL hDir AS DWORD
            LOCAL pOldDACL AS ACL PTR , pNewDACL AS ACL PTR
            LOCAL pSD AS SECURITY_DESCRIPTOR PTR
            LOCAL ea AS EXPLICIT_ACCESS
            LOCAL pstrName AS ASCIIZ * 60
            hDir = CreateFile(lpPath, %READ_CONTROL OR %WRITE_DAC, 0, BYVAL %NULL, %OPEN_EXISTING, %FILE_FLAG_BACKUP_SEMANTICS, %NULL)
            IF hDir = %INVALID_HANDLE_VALUE THEN FUNCTION = %false: EXIT FUNCTION
        
            pstrName = "Users"
            'ACL* pOldDACL=NULL;
            'SECURITY_DESCRIPTOR* pSD = NULL;
            GetSecurityInfo hDir, %SE_FILE_OBJECT, %DACL_SECURITY_INFORMATION, %NULL, %NULL, pOldDACL, %NULL, pSD
        
            ea.grfAccessMode = %GRANT_ACCESS
            ea.grfAccessPermissions = %GENERIC_ALL
            ea.grfInheritance = %CONTAINER_INHERIT_ACE OR %OBJECT_INHERIT_ACE
            ea.Trustee.TrusteeType = %TRUSTEE_IS_GROUP
            ea.Trustee.TrusteeForm = %TRUSTEE_IS_NAME
            ea.Trustee.ptstrName = VARPTR(pstrName)
        
            pNewDACL = %NULL
            SetEntriesInAcl 1, VARPTR(ea), pOldDACL, pNewDACL
        
            SetSecurityInfo hDir, %SE_FILE_OBJECT, %DACL_SECURITY_INFORMATION, %NULL, %NULL, pNewDACL, %NULL
        
            LocalFree pSD
            LocalFree pNewDACL
            CloseHandle hDir
            FUNCTION = %true
        END FUNCTION
        Unfortunately calling GiveDirectoryUserFullAccess with the path returned by the CSIDL did not change anything. Again, I was trying to call CSIDL_COMMON_STARTUP and CSIDL_COMMON_DESKTOPDIRECTORY.

        Regards,

        Peter Redei

        Comment


        • #5
          I see, in this case the mention of Vista's
          "C:\Documents and Settings\All Users\Start Menu\Programs\Startup"
          and "C:\Documents and Settings\All Users\Desktop"
          in your first post meant the "All Users startup folder"
          and the "All Users desktop folder" under Vista.

          If nobody have a quick answer,
          I'll try to do some test with Mike Stefanik's manifest code
          and come back to give result.



          Pierre

          Comment


          • #6
            Just a thought....but could be trailing "\" or one missing

            No time to test, but just a thought
            Engineer's Motto: If it aint broke take it apart and fix it

            "If at 1st you don't succeed... call it version 1.0"

            "Half of Programming is coding"....."The other 90% is DEBUGGING"

            "Document my code????" .... "WHYYY??? do you think they call it CODE? "

            Comment


            • #7
              Good news Peter,

              I did some test with Mike Stefanik's "Elevated privileges manifest"
              and my test program created the shortcut after I answered "Yes"
              to the "Windows needs your permission to continue" dialog box.

              Comment


              • #8
                Thank you Pierre very much. I found Mike's post and just one more question:
                name="My.Program.Name" should be something like
                name="MyPrgrm.exe" or name="MyPrgrm" ? Did you have to do any other changes but the name?

                Thanks again,


                Peter Redei

                Comment


                • #9
                  Hi Peter,

                  For the test, I used the XML file as is without any modification.

                  Comment


                  • #10
                    I reviewed the related Microsoft documentation (http://msdn.microsoft.com/en-us/library/bb756929.aspx). It appears to me the requestedExecutionLevel of the XML should be "highestAvailable" instead of "requireAdministrator". Also if I understand that correctly the user will still need administrator privilege to install shortcut.

                    Peter Redei

                    Comment


                    • #11
                      Peter, I tried your code from the source code forum on my Windows Vista Home Premium laptop. Although after including the manifest, it did create the shortcut, the jellyfish pro editor I launched it from crashed. On rebooting, only lines, no desktop showed on the screen, and I was forced to restore from an earlier restore point. That boot did, however, correctly launch the new shortcut created.

                      To be honest, I've never used WritePrivateProfileString, nor have I used a manifest before. Maybe I just used it wrong... this is the code I used, where cgdSU.exe was just a simple, small executable to try it with.

                      Code:
                      #COMPILE EXE
                      #RESOURCE "test.pbr"
                      #INCLUDE "win32api.inc"
                      
                      FUNCTION WithSlash(a$) AS STRING
                          IF LEN(a$) > 0 THEN
                              IF RIGHT$(a$, 1) <> "\" THEN
                                 WithSlash = a$ + "\"
                              ELSE
                                 WithSlash = a$
                              END IF
                          END IF
                      END FUNCTION
                      
                      FUNCTION GetDestinationFolder(lngLocation AS LONG) AS STRING
                          DIM lpidlStartUp        AS LONG
                          DIM lResult             AS LONG
                          DIM szPathStartUp       AS ASCIIZ * %MAX_PATH
                          lResult = SHGetSpecialFolderLocation(%NULL, lngLocation, lpidlStartUp)
                          IF ISFALSE lResult THEN
                              lResult = SHGetPathFromIDList(BYVAL lpidlStartUp, szPathStartUp)
                              FUNCTION = szPathStartUp
                          END IF
                      END FUNCTION
                      
                      FUNCTION CreateShortcut(sExecutableFileName AS ASCIIZ, sShortcutName AS ASCIIZ) AS LONG
                          LOCAL Res AS LONG
                              
                          Res = %TRUE
                          IF DIR$(sExecutableFileName) = "" THEN
                              MSGBOX "Can`t find executable file!"
                              EXIT FUNCTION
                          END IF
                      
                          Res = WritePrivateProfileString("InternetShortcut", "URL",        sExecutableFileName, sShortcutName)
                          Res = Res AND WritePrivateProfileString("InternetShortcut", "IconIndex",  "0", sShortcutName)
                          Res = Res AND WritePrivateProfileString("InternetShortcut", "IconFile", sExecutableFileName, sShortcutName)
                      
                          FUNCTION = Res
                      END FUNCTION
                      
                      FUNCTION PBMAIN()
                          'change the values as needed
                          LOCAL fn AS ASCIIZ * %max_path
                          LOCAL path AS STRING 
                          fn = "C:\PBWin80\Setup Programs\cgdSU.exe"
                          path = WithSlash(GetDestinationFolder(%CSIDL_COMMON_STARTUP))
                          MSGBOX path
                          CreateShortcut fn, WithSlash(path) & "Property Auction Ticker.url"
                      END FUNCTION

                      and my resource file was simply...
                      Code:
                      #include "resource.h"
                      1 24 "test.manifest"

                      Comment


                      • #12
                        I have some more results. I must be using this program wrong, somehow... and I hope someone can spot what's wrong.

                        Launching 'Compile and run' from Jellyfish Pro again, it crashed (actually, quit responding, forcing me to end it with task manager). But despite this, the shortcut was created, and on rebooting, the desktop displayed this time and the new shortcut correctly launched.

                        Launching 'Compile and run' from the PowerBasic editor, the first time I tried, it did not run, no shortcut created, and since I did not have options set to show errors (my bad), I changed the options, and then it ran fine.

                        Comment

                        Working...
                        X