From: Grand_Poobah on
--->
> ""Jialiang Ge [MSFT]"" <jialge(a)online.microsoft.com> wrote in message
> news:Ofzqy%23Y3IHA.1624(a)TK2MSFTNGHUB02.phx.gbl...
>
>> Regards,
>> Jialiang Ge (jialge(a)online.microsoft.com, remove 'online.')
>> Microsoft Online Community Support
>> =================================================
>> Delighting our customers is our #1 priority.
>
> I was feeling a little bit down today, but you've cheered me up no end.
> It really is comforting to know that people from Micro$oft are out there
> doing their very best to delight us ;-)
>
> Mike
>
>

Wink Wink, Nudge Nudge. Good one.

GP
From: Karl E. Peterson on
Hi Tony --

>>> My test (top post) seems to corroborate those results. What did you use
>>> to make your determination?
>
> Just an educated guess really Karl. It's pretty easy to see that Dir$() is
> stateful, and keeps a handle to the directory open while is returns file
> names from it.

Yeah, that's always been very clear to me, especially after understanding how the
API works. And still it's something that seems to cause no end of surprise and
confusion to language newbs (eg, Jialiang). I thought it might be interesting to
dissect it, and try to explain all its eccentricities.

> Hence, if it isn't called to exhaustion (i.e. where it
> returns a blank) then that handle gets left behind and keeps the directory
> locked.

This is what I've narrowed it down to, so far. (Minus the volume label handling.)

Public Function DirW(Optional ByVal Path As String, Optional Attributes As
VbFileAttribute) As String
Static hFind As Long
Static AttrCache As Long
Dim First As Boolean
Dim wfd As WIN32_FIND_DATA

' Branch based on whether user wants to start a
' new search or continue an old search.
If Len(Path) Then
' Cache requested attributes for Next finds.
AttrCache = Attributes
' Close last search.
If hFind Then Call FindClose(hFind)
' Apply standard VB pathspec assumptions.
Path = VBDirPath(Path)
' Start the search!
First = True
hFind = FindFirstFile(StrPtr(Path), wfd)
End If

If hFind <> INVALID_HANDLE_VALUE Then
Do
' Grab next file, if not first time through.
If First Then
First = False
Else
If (FindNextFile(hFind, wfd) = 0) Then
' All done. Close the search handle.
Call FindClose(hFind)
hFind = 0 'reset
Exit Do
End If
End If

' Apply standard VB attribute filters.
If VBDirInclude(wfd.dwFileAttributes, AttrCache) Then
' Assign results from this find.
DirW = TrimNull(wfd.cFileName)
Exit Do
End If
Loop
End If

' Close handle if user so requested by checking for "nul"
If LCase$(Right$(Path, 3)) = "nul" Then
Call FindClose(hFind)
hFind = 0
End If
End Function

> Another way to force the release of the handle is to move it
> somewhere else (i.e. search a different directory), or better still search
> something that's always going to be there but cannot be locked (hence the
> use of the "nul" device)

That's a great explanation of why this one works!

Thanks... Karl
--
..NET: It's About Trust!
http://vfred.mvps.org


From: Karl E. Peterson on
Hi Jialiang --

Hey, cool! My MSDN sub kicked in, huh? :-)

> I get the symptom reproduced with your VB6 code. In order to see what
> handle is added into the process, I use Process Explorer
> http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
> to view the handle list.

Ahhh, procexp, sure. Shoulda thought of that.

> When Command1 is clicked, process explorer shows that an additional File
> Handle is added named as �C:\? If I click on Command1 again, this handle is
> closed first, then reopened. If I click on Command2, the handle is closed
> and the handle count is deducted by one. This behavior can be consistently
> reproduced.

Yep. It's been doing that since VB1. In fact, much the same mechanism was in play
in the DOS versions of MSBASIC, as they wrapped INT &h21 very similarly.

> I will ask the language team for their explanation.

Good one! Tell 'em "hi!" from me, too, wouldya? :-D

> Karl, would you please
> let me know whether this behavior of Dir has any business impact on your
> product?

Presumably in a negative sense?

Thanks... Karl
--
..NET: It's About Trust!
http://vfred.mvps.org


From: Bob Butler on

"Karl E. Peterson" <karl(a)mvps.org> wrote in message
news:OVWIN1H4IHA.4488(a)TK2MSFTNGP03.phx.gbl...
<cut>
> ' Close handle if user so requested by checking for "nul"
> If LCase$(Right$(Path, 3)) = "nul" Then

I think you need something more like
If LCase$(Right$(Path,4))="\nul" Or LCase$(Path)="nul" Then
as written it fails with a call like DirW("C:\*anynameendingwithnul")


From: Karl E. Peterson on
Bob Butler wrote:
> "Karl E. Peterson" <karl(a)mvps.org> wrote ...
> <cut>
>> ' Close handle if user so requested by checking for "nul"
>> If LCase$(Right$(Path, 3)) = "nul" Then
>
> I think you need something more like
> If LCase$(Right$(Path,4))="\nul" Or LCase$(Path)="nul" Then
> as written it fails with a call like DirW("C:\*anynameendingwithnul")

Good catch! Thanks...
--
..NET: It's About Trust!
http://vfred.mvps.org