Announcement

Collapse
No announcement yet.

Folder Viewer Network Drive Problem

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

  • Folder Viewer Network Drive Problem

    When using folder viewer, if I type or pick a network drive from my history that I have not yet connected to, I get "Folder not available" error. In my case it is my HD at work connected via a vpn and mapped to drive letter. Why can't it prompt for the login like Explorer and other third party apps seem to manage - probably though a simple shell api call?

    It is worth noting that if I use "Browse" and select my mapping it correctly prompts for a login, so why is there this inconsistency?

  • #2
    Re: Folder Viewer Network Drive Problem

    The primary reason we're not using that simple API function is because I haven't figured out what that simple API function is. If I knew what we were doing wrong this would be fixed in the next release.

    As for why the browse dialog works and typing the URL doesn't, the browse dialog uses the shell routines, which internally would call whatever functions are necessary. By that same token if you open the folder in Explorer before running BC it should work too.
    Zoë P Scooter Software

    Comment


    • #3
      Re: Folder Viewer Network Drive Problem

      In this case Beyond Compare should be using the MS Windows Networking Functions, these provide exactly what is needed.

      I can't remember exactly but it could be something like WNetAddConnection2.

      Try here:

      http://msdn.microsoft.com/library/de..._functions.asp

      Comment


      • #4
        Re: Folder Viewer Network Drive Problem

        The reason why shell controls can get network drives to connect, including prompting for user /pw where necessary is an aspect of IShellFolder interface they use. BC can easily achieve the same affect : by simply requesting an IEnumIDList from the drive's IShellFolder interface via the EnumObjects method. I'm pretty sure one benefit IShellFolder approach has over WNetAddConnection2, is that it will recall last username etc.

        I'll see if I can knock up some Delphi code to do it tomorrow.
        Paul
        IDS Ltd

        Comment


        • #5
          Re: Folder Viewer Network Drive Problem

          Paul: thanks for the help. Did you find this out on your own or do you have a link to some documentation suggesting it?

          Anonymous: I have a build that implements what Paul suggested (we were already using WNetAddConnection2). If you email support I'll send you a copy so you can confirm whether this fixed the problem.
          Zoë P Scooter Software

          Comment


          • #6
            Re: Folder Viewer Network Drive Problem

            Craig : I remember reading a newsgroup posting once about reconnecting to network drives somewhere using IShellFolder. It seems to be one of those "tricks or the trade" type things that MS never document but people have found out.

            If you are interested, I have tested my "ConnectToPath" routine below which works fine reconnecting a network drive in my case 'T:\', including prompting for user and pw. I haven't tested it for situations like connecting to a drive with path. e.g. 'T:\windows', but I suppose you could connect to drive first then path. It is worth noting that the IShellFolder.EnumObjects needs an owner window handle for the standard windows login to appear (if required). Also, there is no need to iterate the whole EnumObjects list, which can be very slow in some scenarios.
            Hope this helps!

            Paul Scott
            IDS Ltd

            //===================
            Code:
             
            
            uses
              ShlObj, ActiveX, ComObj;
             
             
            function GetHasSubItems(hwndOwner : HWnd; ShellFolder: IShellFolder; Flags: Integer): Boolean;
            // Finds if a shellfolder has children - a side effect of which is reconnecting network connections
            // Note : If user input is required to perform the enumeration (username and password dialog)
            // hwndOwner must be a owner form handle, If hwndOwner = 0 the connection
            // and user input is required, it will silently fail.
            var
              ID: PItemIDList;
              EnumList: IEnumIDList;
              NumIDs: LongWord;
              HR: HResult;
              ErrMode: Integer;
            begin
              Result := False;
              if ShellFolder = nil then
                Exit;
              ErrMode := SetErrorMode(SEM_FAILCRITICALERRORS);
              try
                HR := ShellFolder.EnumObjects(hwndOwner, Flags, EnumList);
                if HR <> S_OK then
                  Exit;
                Result := EnumList.Next(1, ID, NumIDs) = S_OK;
              finally
                SetErrorMode(ErrMode);
              end;
            end;
             
            function GetPIDLFromPath(const APath : string): PItemIDList;
            var
              OLEStr: array[0..Max_Path] of TOleChar;
              piDesktop: IShellFolder;
              ulEaten, ulAttribs: ULong;
            begin
              Result := nil;
              if Succeeded(SHGetDesktopFolder(piDesktop)) then
              begin
                piDesktop._AddRef;
                if Failed(piDesktop.ParseDisplayName(0, nil, StringToWideChar(APath, OLEStr, MAX_PATH), ulEaten, Result, ulAttribs)) then
                  Result := nil;
              end;
            end;
             
            function GetPIDLShellFolder(pidl: PItemIDList; var piFolder: IShellFolder) : boolean;
            var
              piDesktopFolder: IShellFolder;
            begin
              Result := False;
              if Succeeded(SHGetDesktopFolder(piDesktopFolder)) then // Find desktop pidl
              begin
                if (not assigned(piFolder)) and Failed(SHGetDesktopFolder(piFolder)) then
                  exit;
                if (not Failed(piDesktopFolder.BindToObject(pidl, nil, IID_IShellFolder, pointer(piFolder)))) or  //Retrieve IShellFolder object for subfolder.
                   (assigned(pidl) and (pidl^.mkid.cb = 0)) then
                  Result := True;
              end;
            end;
             
            function ConnectToPath(hwndOwner : HWnd; const APath : string) : boolean;
            // Connects to a path, including reconnecting network connections
            // Note : If user input is required to perform the connection (username and password dialog)
            // hwndOwner must be a owner form handle, If hwndOwner = 0 the connection
            // and user input is required, it will silently fail.
            var
              ItemIDList : PItemIDList;
              ShellFolder : IShellFolder;
            begin
              Result := False;
              ItemIDList := GetPIDLFromPath(APath);
              if (ItemIDList <> nil) and (GetPIDLShellFolder(ItemIDList, ShellFolder)) then
                Result := GetHasSubItems(hwndOwner, ShellFolder, SHCONTF_FOLDERS or SHCONTF_INCLUDEHIDDEN);
            end;
             
            //-------------------- Test Code -------------------
             
            procedure TForm1.Button1Click(Sender: TObject);
            begin
              if ConnectToPath(Self.Handle, 'T:\') then
                Showmessage('Yes')
              else
                Showmessage('No');
            end;

            Comment


            • #7
              Re: Folder Viewer Network Drive Problem

              Paul,

              Thanks for the code. Something like this is integrated into the 2.4 beta, but I did stick with calling WNetAddConnection first. I'd appreciate it if someone who can repeat this reliably could test it and make sure it's actually fixed.
              Zoë P Scooter Software

              Comment

              Working...
              X