Jump to content

ABANDONED: FileSelectFolder: long delay before dialog appears

Recommended Posts


I've abandoned the FileSelectFolder() approach and rolled my own UDF to create a dialog containing the folder list in a ListView, which seems to work fine. It's also a better fit to our requirements: we don't really want the user wandering around in the folder-selection dialog, plus the UDF displays some associated info for each folder in a second column. Thanks again to the forum members who took a look at this. :)

I'm writing an installer script that needs to run as Administrator so it can, e.g., write files into protected directories. The problem is that when I call FileSelectFolder(), there is a 60-second delay before the dialog appears. If I run as an ordinary user (in the Administrators group), there's no delay, but I don't think that will work: for one thing, the installer needs to create a symbolic link, which a member of the Administrators group can't do unless the program is elevated. (This is Win 7 x64.)

(The installer will be run using an Admin account; the other user accounts are locked down and don't have access to the filesystem, the Start menu, Computer, etc. - it's a turnkey system.)

Any idea what causes the delay? And is there a way around it?


Edited by tremolux66
Question has become OBE.

When the going gets tough, the tough start coding.

Share this post

Link to post
Share on other sites

have you checked the value Initial Dir ?? 

Share this post

Link to post
Share on other sites

I left Initial Dir at the default value - empty string - which worked in the example code. If I understand that parameter correctly it's an initial folder selection, which we don't actually want or need b/c there is no default in this case; the dialog works as desired once it appears.

The installer script displays the dialog immediately with the default value when it's run unelevated, but has the delay with Run as administrator or #RequireAdmin.

(BTW, my AutoIt version is

When the going gets tough, the tough start coding.

Share this post

Link to post
Share on other sites

Have you confirmed the delay is specifically when the FileSelectFolder line is executed?

If you insert a debug right before it, does it immediately show, and then subsequently the delay occurs?  Just making sure the issue is narrowed down.  What does the whole FileSelectFolder line in your script look like?

Share this post

Link to post
Share on other sites

Here's a fragment of the code surrounding the FileSelectFolder() call:

If $iBtnNum = 2 Then
    ; Prompt user for the new build folder and restore it
    _LogWrite("Getting the build to be restored...")
    While 1
        ; Get the full path of the restoration-build folder
        _LogDebug("Calling FileSelectFolder w/root dir='" & $cWinInstRoot & "'")
        $sWinRestInstPath = FileSelectFolder("Select the build to restore", $cWinInstRoot)
        If @error Then
            ; User canceled the dialog
            _LogWrite("User canceled restore (folder select dialog)")

        ; If it's the directory pointed to by the active link, display an error and retry
        $sTemp = _GetReparseTarget($cWinActiveLink)     ; From ReparseUtils.au3 UDF
        If $sWinRestInstPath = $sTemp Then
            MsgBox($cMsgBoxFlags, $cWinErrTitle, "ERROR: Selected build is the active build --" & @CRLF & _
                                @TAB & "choose a different build")

        _LogDebug("WinRestInstPath='" & $sWinRestInstPath & "'")
        ; ...
    ; ...

The message from the _LogDebug() immediately preceding the FileSelectFolder() shows up in the installer's GUI: it has an edit control that displays the messages from the _Log*() functions. When the compiled installer is running elevated, a spinning wait-cursor appears for 60 seconds, then the FSF dialog appears and execution proceeds as expected. Without elevation, the FSF dialog appears immediately, but then the script doesn't have admin privileges.

When the going gets tough, the tough start coding.

Share this post

Link to post
Share on other sites

Dang, nothing obvious popping out here.  What is the value of $cWinInstRoot and how does it get set?  Sorry, grasping at straws here.

Share this post

Link to post
Share on other sites

It's the path to the root of the installation folders & is a constant; it's set to something like "C:\Program Files\MyCompany". The "Win" component of the constant name indicates it's a Windows path (vs. "Cyg" for a Cygwin path).

We install the software builds under the root folder in directories with names of the form "MyProduct_yyyymmdd_n" (yyyymmdd_n translates to yyyy.[m]m.[d]d.n as a file version number in the .exe files). We generally leave all the installed versions in place, and create a symlink "MyProduct" to point to the active version (hence the reparse point check in the code). To switch versions like we're doing in the code above, we essentially delete the current symlink and create a new one that points to the desired folder. (There's a bit more to it than that, but you get the idea.) The software is designed to look for programs and reference data files under "C:\Program Files\MyCompany\MyProduct".

(And thanks to everyone who's looking at this. :))

When the going gets tough, the tough start coding.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • Gringo
      By Gringo
      I'm trying to:
      -Select a file in a folder (to store it to an ini file)
      -Write the file on an ini
      -Copy files to the folder selected by the user
      instead of using FileOpenDialog then FileSelectFolder, I was wondering if it was possible to do the whole thing only with FileOpenDialog spliting the value returned in 2 variables. I got something like that for the first part (select a file and store it to an ini file)
      Local $message = "Select your executable" Local $pathk = FileOpenDialog($message, "C:" & "", "Select the executable you want to terminate (*.exe)", 1 + 4) Local $path = "None" ;ici je dois copier les fichiers $split = StringSplit($pathk, "\") $tokill = $split[$split[0]] If @error Then MsgBox(4096, "", "No Executable chosen") Else MsgBox(4096, "", $pathk & " Will be terminated " & @LF & @LF & "Press OK to EXIT ") IniWrite(@ScriptDir & "\path.ini", "Torun", "path", $path) IniWrite(@ScriptDir & "\path.ini", "Tokill", "pathk", $tokill) EndIf As you can see I manage to split the value returned by FileOpenDialog to have only the exe but as a noob I can't manage to get the path to copy the files I need to the same path.
      Any idea? ^^
    • RC86
      By RC86
      Morning! I've searched for a definitive answer on the forums on this but can't find one so here goes.  I need admin for one of my functions so I'm using #RequireAdmin.  I then noticed that regardless of that function being used or admin actually being required, the program pops up and requires admin all of the time.
      Is this the way it's designed and is there a way around it so that I can launch my program as normal until admin is required, then and only then prompt the user to run the program as admin?
      The only solution I could think of is to produce 2 executables and do something like:
      $adminrequired = 1 If($adminrequired = 1) Then Run(Run first executable which includes #RequireAdmin) Else Run(Run second identical executable without #RequireAdmin) EndIf Obviously I'd rather keep to making a single executable rather than having 2 or 3!
    • qwert
      By qwert
      After a few weeks of researching and testing, I think I have a good understanding of #RequireAdmin and IsAdmin() for an individual script.  They both work in conjunction with each other and ignore whether the current user has administrator rights, or not.  In other words, IsAdmin() doesn't test the user, only the declared permission level of the script it is executed in.  A separate check is needed to actually confirm the user's admin level.  I've included a test script that demonstrates the difference.
      Here is my question:  When a compiled scripts runs with administrative rights, does a script that it runs inherit those rights?  Or is every script on its own?  For example,
      Parent Script ... (doesn't need admin rights) ... that runs:
      Child Script ... that does need admin rights, and obtains them via #RequireAdmin + user's response ... and then runs:
      2nd Child Script ...<< does this script execute with admin rights, or not? 
      If a script does not automatically inherit rights, then is there a way for a parent script that has admin rights to run a child script "with rights", so that running the child script does not result in another prompt for user permission?
      Thanks in advance for any help.
      ;#RequireAdmin ; enable or disable this line to see the difference $AdCheck = IsAdmin() MsgBox(0, "Admin Test", "Admin is " & $AdCheck) $AdCheck = _IsAdministrator() MsgBox(0, "Admin Test", "Admin is " & $AdCheck) Exit Func _IsAdministrator($sUser = @UserName, $sCompName = ".") Local $aCall = DllCall("netapi32.dll", "long", "NetUserGetInfo", "wstr", $sCompName, "wstr", $sUser, "dword", 1, "ptr*", 0) If @error Or $aCall[0] Then Return SetError(1, 0, False) Local $fPrivAdmin = DllStructGetData(DllStructCreate("ptr;ptr;dword;dword;ptr;ptr;dword;ptr", $aCall[4]), 4) = 2 DllCall("netapi32.dll", "long", "NetApiBufferFree", "ptr", $aCall[4]) Return $fPrivAdmin EndFunc  
    • TheDcoder
      By TheDcoder
      Hello! , I have a little doubt about the "root dir" parameter in FileSelectFolder, The helpfile states:
      1. GUI file tree? Isn't that something like this?:

      But the dialog for selecting a folder in FileSelectFolder is similar to the dialog of FileOpenDialog
      2. "It limits the choice in the root folder"... "" is considered to be @DesktopDir, then why am I able to select folders outside the Desktop folder?
      Thanks in Advance, TD
    • lrstndm
      By lrstndm
      Hi all,
      I have a problem with a script when I run it as admin. I am trying to get all the mapped drives from the local pc. This is the script I am using
      ;~ #RequireAdmin ; This switch is going wrong #include <Array.au3> If isAdmin() then MsgBox(0,"ADMIN","ADMIN") Else MsgBox(0,"NOT ADMIN","NOT ADMIN") EndIf $x = getMappedDrives() _ArrayDisplay($x) Func getMappedDrives() Dim $aDrives[0][2] $objWMIService = ObjGet("winmgmts:\\" & @LogonDomain & "\root\CIMV2") $sQuery = "Select * From Win32_LogicalDisk Where DriveType = 4" $colItems = $objWMIService.ExecQuery($sQuery, "WQL", 48) If IsObj($colItems) Then For $objItem In $colItems ReDim $aDrives[UBound($aDrives) + 1][2] $aDrives[UBound($aDrives) - 1][0] = $objItem.DeviceID $aDrives[UBound($aDrives) - 1][1] = $objItem.ProviderName Next Return $aDrives Else SetError(-1, -1, -1) EndIf EndFunc When I run it without the '#RequireAdmin' switch it works fine. When I turn on the '#RequireAdmin' switch is gives me an empty array.
      This code is part of a bigger project and my project always runs as admin. I dont know why it is doing this, because I am not using #RequireAdmin in the project.
      Is there an other better way to get the mapped drives that works for me? Or am I doing something wrong?
      I hope someone can help me.

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.