Author: Joe Yoder
Posted: 2011-02-17 20:59:50 Link
I want to store a copy of the complete directory structure of each optical disc in my media storage system in a VFP table memo field. I considered using recursion with adir() but concluded that it makes more sense to use something like the Windows internal command "dir" with the "/s"subdirectories option as this automatically includes file and folder sizes.
I have been experimenting with Microsoft example code which uses CreateProcess and WaitForSingleObject and can have it execute an exe such as Notepad and wait for it to be closed before returning control to VFP. When I try to execute the command "Dir" rather than "C:\Windows\System32\Notepad" I get an error. I think the difference is that 'Dir" is an internal command but maybe it is just a syntax problem.
Can someone help me out with the correct CreateProcess syntax or point me to another function?
As always - a suggestion for another approach would also be welcome.
TIA - Joe
--- StripMime Report -- processed MIME parts ---
multipart/alternative
text/plain (text body -- kept)
text/html
---
_______________________________________________
Post Messages to: ProFox@leafe.com
Subscription Maintenance: http://leafe.com/mailman/listinfo/profox
OT-free version of this list: http://leafe.com/mailman/listinfo/profoxtech
Searchable Archive: http://leafe.com/archives/search/profox
This message: http://leafe.com/archives/byMID/profox/4d5dd2ac.26092a0a.2289.383a@mx.google.com
** All postings, unless explicitly stated otherwise, are the opinions of the author, and do not constitute legal or medical advice. This statement is added to the messages for those lawyers who are too stupid to see the obvious.
Author: Grigore Dolghin
Posted: 2011-02-18 01:22:36 Link
Function DoAndWait(cExe, cWindowMode)
Declare Integer CreateProcess In kernel32.Dll ;
INTEGER lpApplicationName, ;
STRING lpCommandLine, ;
INTEGER lpProcessAttributes, ;
INTEGER lpThreadAttributes, ;
INTEGER bInheritHandles, ;
INTEGER dwCreationFlags, ;
INTEGER lpEnvironment, ;
INTEGER lpCurrentDirectory, ;
STRING @lpStartupInfo, ;
STRING @lpProcessInformation
Declare Integer WaitForSingleObject In kernel32.Dll ;
INTEGER hHandle, ;
INTEGER dwMilliseconds
Declare Integer CloseHandle In kernel32.Dll ;
INTEGER hObject
#Define NORMAL_PRIORITY_CLASS 32
#Define IDLE_PRIORITY_CLASS 64
#Define HIGH_PRIORITY_CLASS 128
#Define REALTIME_PRIORITY_CLASS 1600
* Return code from WaitForSingleObject() if * it timed out.
#Define WAIT_TIMEOUT 0x00000102
* This controls how long, in milli secconds, WaitForSingleObject()
* waits before it times out. Change this to suit your preferences.
#Define WAIT_INTERVAL 200
* STARTUPINFO is 68 bytes, of which we need to
* initially populate the 'cb' or Count of Bytes member
* with the overall length of the structure.
* The remainder should be 0-filled
* cStartUpInfo = long2str(68) + Replicate(Chr(0), 64)
If (Vartype(cWindowMode) # "C") Or (Not Inlist(cWindowMode, "NOR",
"MIN", "MAX", "HID"))
cWindowMode = "" && Use default of application
Endif
cWindowMode = Upper(cWindowMode)
Do Case
Case cWindowMode = "HID"
* Hide - use STARTF_USESHOWFLAG and value of 0
cStartUpInfo = Chr(68) + Repl(Chr(0), 43) + Chr(1) +
Repl(Chr(0), 3) + Chr(0) + Repl(Chr(0), 19)
Case cWindowMode = "NOR"
* Normal - use STARTF_USESHOWFLAG and value of 1
cStartUpInfo = Chr(68) + Repl(Chr(0), 43) + Chr(1) +
Repl(Chr(0), 3) + Chr(1) + Repl(Chr(0), 19)
Case cWindowMode = "MIN"
* Minimize - use STARTF_USESHOWFLAG and value of 2
cStartUpInfo = Chr(68) + Repl(Chr(0), 43) + Chr(1) +
Repl(Chr(0), 3) + Chr(2) + Repl(Chr(0), 19)
Case cWindowMode = "MAX"
* Maximize - use STARTF_USESHOWFLAG and value of 3
cStartUpInfo = Chr(68) + Repl(Chr(0), 43) + Chr(1) +
Repl(Chr(0), 3) + Chr(3) + Repl(Chr(0), 19)
Otherwise
* Use default of application
cStartUpInfo = Chr(68) + Repl(Chr(0), 43) + Chr(0) +
Repl(Chr(0), 3) + Chr(0) + Repl(Chr(0), 19)
Endcase
* PROCESS_INFORMATION structure is 4 longs,
* or 4*4 bytes = 16 bytes, which we'll fill with nulls.
cProcessInfo = Replicate(Chr(0), 16)
* EXE name must be null-terminated
cExe = cExe + Chr(0)
* Call CreateProcess, obtain a process handle. Treat the
* application to run as the 'command line' argument, accept
* all other defaults. Important to pass the cStartUpInfo and
* cProcessInfo by reference.
RetCode = CreateProcess(0, cExe, 0, 0, 1, ;
NORMAL_PRIORITY_CLASS, 0, 0, @cStartUpInfo, @cProcessInfo)
* Unable to run, exit now. IF RetCode = 0 RETURN .F. ENDIF
* Extract the process handle from the
* PROCESS_INFORMATION structure.
hProcess = str2long( Substr( cProcessInfo, 1, 4))
Do While .T.
* Use timeout of TIMEOUT_INTERVAL msec so the display
* will be updated. Otherwise, the VFP window never repaints until
* the loop is exited.
If WaitForSingleObject( hProcess, WAIT_INTERVAL) != WAIT_TIMEOUT
Exit
Else
DoEvents
Endif
Enddo
* Close the process handle afterwards.
RetCode = CloseHandle( hProcess)
Return .T.
Endfunc
**************************************************************
*--
Function Long2Str(tnLongVal)
Local lcResult, i
#If Version(5) >= 900
lcResult = BinToC(tnLongVal, [4RS])
#Else
lcResult = ""
For i = 24 To 0 Step -8
lcResult = Chr(Int(tnLongVal / (2 ^ i))) + lcResult
tnLongVal = Mod(tnLongVal, (2 ^ i))
Endfor
#Endif
Return lcResult
Endfunc
*--
Function Str2Long(tcLongStr)
Local lnResult, i
#If Version(5) >= 900 Then
lnResult = CToBin(tcLongStr, [4RS])
#Else
lnResult = 0
For i = 0 To 24 Step 8
lnResult = lnResult + (Asc(tcLongStr) * (2 ^ i))
tcLongStr = Right(tcLongStr, Len(tcLongStr) - 1)
Endfor
#Endif
Return lnResult
Endfunc
> -----Original Message-----
> From: profoxtech-bounces@leafe.com [mailto:profoxtech-
> bounces@leafe.com] On Behalf Of Joe Yoder
> Sent: Friday, February 18, 2011 4:00 AM
> To: profoxtech@leafe.com
> Subject: Getting a complete file list from a removable disc into VFP
>
> I want to store a copy of the complete directory structure of each optical
disc
> in my media storage system in a VFP table memo field. I considered using
> recursion with adir() but concluded that it makes more sense to use
> something like the Windows internal command "dir" with the
> "/s"subdirectories option as this automatically includes file and folder
sizes.
>
> I have been experimenting with Microsoft example code which uses
> CreateProcess and WaitForSingleObject and can have it execute an exe such
> as Notepad and wait for it to be closed before returning control to VFP.
> When I try to execute the command "Dir" rather than
> "C:\Windows\System32\Notepad" I get an error. I think the difference is
> that 'Dir" is an internal command but maybe it is just a syntax problem.
>
> Can someone help me out with the correct CreateProcess syntax or point me
> to another function?
>
> As always - a suggestion for another approach would also be welcome.
>
> TIA - Joe
>
>
> --- StripMime Report -- processed MIME parts --- multipart/alternative
> text/plain (text body -- kept)
> text/html
> ---
>
[excessive quoting removed by server]
_______________________________________________
Post Messages to: ProFox@leafe.com
Subscription Maintenance: http://leafe.com/mailman/listinfo/profox
OT-free version of this list: http://leafe.com/mailman/listinfo/profoxtech
Searchable Archive: http://leafe.com/archives/search/profox
This message: http://leafe.com/archives/byMID/profox/000001cbcf34$3cfc2e40$b6f48ac0$@gmail.com
** All postings, unless explicitly stated otherwise, are the opinions of the author, and do not constitute legal or medical advice. This statement is added to the messages for those lawyers who are too stupid to see the obvious.
Author: Alan Bourke
Posted: 2011-02-18 04:05:06 Link
On Thu, 17 Feb 2011 20:59 -0500, "Joe Yoder" <joe@wheypower.com> wrote:
> I want to store a copy of the complete directory structure of each
> optical disc in my media storage system in a VFP table memo field. I
> considered using recursion with adir() but concluded that it makes more
> sense to use something like the Windows internal command "dir" with the
> "/s"subdirectories option as this automatically includes file and folder
> sizes.
ADIR() includes sizes ... this might be an alternative without resorting
to the Windows API:
http://fox.wikis.com/wc.dll?Wiki~RecursiveDirectoryProcessing
--
Alan Bourke
alanpbourke (at) fastmail (dot) fm
_______________________________________________
Post Messages to: ProFox@leafe.com
Subscription Maintenance: http://leafe.com/mailman/listinfo/profox
OT-free version of this list: http://leafe.com/mailman/listinfo/profoxtech
Searchable Archive: http://leafe.com/archives/search/profox
This message: http://leafe.com/archives/byMID/profox/1298019906.27685.1421333407@webmail.messagingengine.com
** All postings, unless explicitly stated otherwise, are the opinions of the author, and do not constitute legal or medical advice. This statement is added to the messages for those lawyers who are too stupid to see the obvious.
Author: Stephen Russell
Posted: 2011-02-18 09:16:34 Link
On Thu, Feb 17, 2011 at 7:59 PM, Joe Yoder <joe@wheypower.com> wrote:
> I want to store a copy of the complete directory structure of each optical disc in my media storage system in a VFP table memo field. I considered using recursion with adir() but concluded that it makes more sense to use something like the Windows internal command "dir" with the "/s"subdirectories option as this automatically includes file and folder sizes.
>
> I have been experimenting with Microsoft example code which uses CreateProcess and WaitForSingleObject and can have it execute an exe such as Notepad and wait for it to be closed before returning control to VFP. When I try to execute the command "Dir" rather than "C:\Windows\System32\Notepad" I get an error. I think the difference is that 'Dir" is an internal command but maybe it is just a syntax problem.
>
> Can someone help me out with the correct CreateProcess syntax or point me to another function?
>
> As always - a suggestion for another approach would also be welcome.
--------------------
dir /s >c:\sometextfile.txt
Then suck in those text files into your memo.
--
Stephen Russell
Sr. Production Systems Programmer
CIMSgts
901.246-0159 cell
_______________________________________________
Post Messages to: ProFox@leafe.com
Subscription Maintenance: http://leafe.com/mailman/listinfo/profox
OT-free version of this list: http://leafe.com/mailman/listinfo/profoxtech
Searchable Archive: http://leafe.com/archives/search/profox
This message: http://leafe.com/archives/byMID/profox/AANLkTimA7mUk7avbFn6JO+tMTk6KdYEvkgW2kJY3cBur@mail.gmail.com
** All postings, unless explicitly stated otherwise, are the opinions of the author, and do not constitute legal or medical advice. This statement is added to the messages for those lawyers who are too stupid to see the obvious.
Author: Tracy Pearson
Posted: 2011-02-18 13:02:17 Link
Grigore Dolghin wrote on 2011-02-18:
> hProcess = str2long( Substr( cProcessInfo, 1, 4))
> Do While .T.
> * Use timeout of TIMEOUT_INTERVAL msec so the display
> * will be updated. Otherwise, the VFP window never repaints until
> * the loop is exited.
> If WaitForSingleObject( hProcess, WAIT_INTERVAL) != WAIT_TIMEOUT
> Exit
> Else
> DoEvents
> Endif
> Enddo
Grigore,
I thought you might like to check on this. The above Do While loop you have
will peg a processor and slow down the process you are waiting for. Adding a
call to the Sleep(1) API or using an INKEY(.1) will keep this from being
resource hungry.
DECLARE Integer Sleep IN WIN32API Integer
Tracy Pearson
PowerChurch Software
_______________________________________________
Post Messages to: ProFox@leafe.com
Subscription Maintenance: http://leafe.com/mailman/listinfo/profox
OT-free version of this list: http://leafe.com/mailman/listinfo/profoxtech
Searchable Archive: http://leafe.com/archives/search/profox
This message: http://leafe.com/archives/byMID/profox/001601cbcf95$fb6247f0$f226d7d0$@com
** All postings, unless explicitly stated otherwise, are the opinions of the author, and do not constitute legal or medical advice. This statement is added to the messages for those lawyers who are too stupid to see the obvious.
Author: Ted Roche
Posted: 2011-02-18 13:36:59 Link
On Thu, Feb 17, 2011 at 8:59 PM, Joe Yoder <joe@wheypower.com> wrote:
> I want to store a copy of the complete directory structure of each optical disc in my media storage system in a VFP table memo field. I considered using recursion with adir() but concluded that it makes more sense to use something like the Windows internal command "dir" with the "/s"subdirectories option as this automatically includes file and folder sizes.
>
> I have been experimenting with Microsoft example code which uses CreateProcess and WaitForSingleObject and can have it execute an exe such as Notepad and wait for it to be closed before returning control to VFP. When I try to execute the command "Dir" rather than "C:\Windows\System32\Notepad" I get an error. I think the difference is that 'Dir" is an internal command but maybe it is just a syntax problem.
>
> Can someone help me out with the correct CreateProcess syntax or point me to another function?
>
> As always - a suggestion for another approach would also be welcome.
>
This is an old problem that's been solved before. VFP already has
hooks into the underlying OS functionality, so there's no need to
build up your own API calls and handle the timing issues. Take a look
at:
http://fox.wikis.com/wc.dll?Wiki~RecursiveDirectoryProcessing
--
Ted Roche
Ted Roche & Associates, LLC
_______________________________________________
Post Messages to: ProFox@leafe.com
Subscription Maintenance: http://leafe.com/mailman/listinfo/profox
OT-free version of this list: http://leafe.com/mailman/listinfo/profoxtech
Searchable Archive: http://leafe.com/archives/search/profox
This message: http://leafe.com/archives/byMID/profox/AANLkTin9E2iX=YsQGjKLSy9W5N+rPH6Dic98FcRMTm4v@mail.gmail.com
** All postings, unless explicitly stated otherwise, are the opinions of the author, and do not constitute legal or medical advice. This statement is added to the messages for those lawyers who are too stupid to see the obvious.
Author: Joe Yoder
Posted: 2011-02-18 17:04:38 Link
Tracy,
I believe every version of code I have looked at uses the routine listed
here. Can you be more specific about where the sleep or inkey should be
added?
Thanks - Joe
On Friday, February 18, 2011 1:02 PM, Tracy Pearson wrote:
>
>Date: Fri, 18 Feb 2011 13:02:17 -0500
>From: Tracy Pearson
>To: profoxtech@leafe.com
>cc:
>Subject: RE: Getting a complete file list from a removable disc into VFP
>
>Grigore Dolghin wrote on 2011-02-18:
>
>> hProcess = str2long( Substr( cProcessInfo, 1, 4))
>> Do While .T.
>> * Use timeout of TIMEOUT_INTERVAL msec so the display
>> * will be updated. Otherwise, the VFP window never repaints until
>> * the loop is exited.
>> If WaitForSingleObject( hProcess, WAIT_INTERVAL) != WAIT_TIMEOUT
>> Exit
>> Else
>> DoEvents
>> Endif
>> Enddo
>
>Grigore,
>
>I thought you might like to check on this. The above Do While loop you have
>will peg a processor and slow down the process you are waiting for. Adding a
>call to the Sleep(1) API or using an INKEY(.1) will keep this from being
>resource hungry.
>
> DECLARE Integer Sleep IN WIN32API Integer
>
>Tracy Pearson
>PowerChurch Software
>
>
>
>
[excessive quoting removed by server]
_______________________________________________
Post Messages to: ProFox@leafe.com
Subscription Maintenance: http://leafe.com/mailman/listinfo/profox
OT-free version of this list: http://leafe.com/mailman/listinfo/profoxtech
Searchable Archive: http://leafe.com/archives/search/profox
This message: http://leafe.com/archives/byMID/profox/4d5eed52.29d6e70a.50ab.64ab@mx.google.com
** All postings, unless explicitly stated otherwise, are the opinions of the author, and do not constitute legal or medical advice. This statement is added to the messages for those lawyers who are too stupid to see the obvious.
Author: Tracy Pearson
Posted: 2011-02-18 18:08:05 Link
Joe Yoder wrote on 2011-02-18:
> Tracy,
>
> I believe every version of code I have looked at uses the routine
> listed here. Can you be more specific about where the sleep or inkey
> should be added?
>
> Thanks - Joe
>
Joe,
With the DoEvents command, before or after.
Tracy Pearson
PowerChurch Software
_______________________________________________
Post Messages to: ProFox@leafe.com
Subscription Maintenance: http://leafe.com/mailman/listinfo/profox
OT-free version of this list: http://leafe.com/mailman/listinfo/profoxtech
Searchable Archive: http://leafe.com/archives/search/profox
This message: http://leafe.com/archives/byMID/profox/002d01cbcfc0$b3b2a190$1b17e4b0$@com
** All postings, unless explicitly stated otherwise, are the opinions of the author, and do not constitute legal or medical advice. This statement is added to the messages for those lawyers who are too stupid to see the obvious.
Author: Joe Yoder
Posted: 2011-02-18 20:37:05 Link
Tracy and all,
I am trying to develop some competence with API calls so I setup a simple
bench mark and had the Performance tab on Task Manager up while I ran
several tests. Here is the test routine:
* Test DoAndWait performance
* Save the start time
m.StTm = VAL(SYS(2))
* Do the call - Uncomment the one being tested
?DoAndWait("c:\windows\system32\notepad.exe Contents.txt", "NOR")
*?DoAndWait("c:\windows\system32\cmd.exe /c dir c:\ /s", "HID")
*?DoAndWait("c:\windows\system32\cmd.exe /c dir c:\ /s>Contents.txt",
"HID")
* report the elapsed time
?ALLTRIM(STR(VAL(SYS(2)) - m.StTm)) + ' Seconds this run'
I tried the inkey(.1) both before and after the DO EVENTS line. I could
not tell any difference in the CPU utilization with or without the
inkey(.1) enabled in the code. The directory scan run durations were
also the same with or without the inkey(.1).
I was surprised to see that the directory redirected to a file ran in 5
or 6 seconds while the one going nowhere took 11 or 12 seconds.
I would be glad for an explanation of what is causing these results but a
grateful that I can at least achieve them now.
I stumbled across the "cmd.exe /c dir" syntax as a way to execute an
internal command but have never found any documentation about when this
is necessary. Where can I find this information?
It appears that one needs to convert long filenames to the 8.3 format
before passing them as parameters on a command line to the CreateProcess
routine. Is this something that applies to all API calls?
Thanks to all who helped me with this,
Joe
On Friday, February 18, 2011 6:08 PM, Tracy Pearson wrote:
>
>Date: Fri, 18 Feb 2011 18:08:05 -0500
>From: Tracy Pearson
>To: profoxtech@leafe.com
>cc:
>Subject: RE: Getting a complete file list from a removable disc into VFP
>
>Joe Yoder wrote on 2011-02-18:
>> Tracy,
>>
>> I believe every version of code I have looked at uses the routine
>> listed here. Can you be more specific about where the sleep or inkey
>> should be added?
>>
>> Thanks - Joe
>>
>
>Joe,
>
>With the DoEvents command, before or after.
>
>Tracy Pearson
>PowerChurch Software
>
>
>
>
[excessive quoting removed by server]
_______________________________________________
Post Messages to: ProFox@leafe.com
Subscription Maintenance: http://leafe.com/mailman/listinfo/profox
OT-free version of this list: http://leafe.com/mailman/listinfo/profoxtech
Searchable Archive: http://leafe.com/archives/search/profox
This message: http://leafe.com/archives/byMID/profox/4d5f1f01.c438e70a.7164.6a62@mx.google.com
** All postings, unless explicitly stated otherwise, are the opinions of the author, and do not constitute legal or medical advice. This statement is added to the messages for those lawyers who are too stupid to see the obvious.
Author: Tracy Pearson
Posted: 2011-02-22 11:15:00 Link
Joe Yoder wrote on 2011-02-18:
> Tracy and all,
>
> I am trying to develop some competence with API calls so I setup a
> simple bench mark and had the Performance tab on Task Manager up while
> I ran several tests. Here is the test routine:
>
> * Test DoAndWait performance
> * Save the start time
> m.StTm = VAL(SYS(2))
> * Do the call - Uncomment the one being tested
> ?DoAndWait("c:\windows\system32\notepad.exe Contents.txt", "NOR")
> *?DoAndWait("c:\windows\system32\cmd.exe /c dir c:\ /s", "HID")
> *?DoAndWait("c:\windows\system32\cmd.exe /c dir c:\ /s>Contents.txt",
"HID")
>
> * report the elapsed time
> ?ALLTRIM(STR(VAL(SYS(2)) - m.StTm)) + ' Seconds this run'
> I tried the inkey(.1) both before and after the DO EVENTS line. I could
> not tell any difference in the CPU utilization with or without the
> inkey(.1) enabled in the code. The directory scan run durations were
> also the same with or without the inkey(.1).
>
> I was surprised to see that the directory redirected to a file ran in
> 5 or 6 seconds while the one going nowhere took 11 or 12 seconds.
>
> I would be glad for an explanation of what is causing these results
> but a grateful that I can at least achieve them now.
>
> I stumbled across the "cmd.exe /c dir" syntax as a way to execute an
> internal command but have never found any documentation about when
> this is necessary. Where can I find this information?
>
> It appears that one needs to convert long filenames to the 8.3 format
> before passing them as parameters on a command line to the CreateProcess
> routine. Is this something that applies to all API calls?
>
> Thanks to all who helped me with this,
>
> Joe
Joe,
> *?DoAndWait("c:\windows\system32\cmd.exe /c dir c:\ /s", "HID")
> I was surprised to see that the directory redirected to a file ran in
> 5 or 6 seconds while the one going nowhere took 11 or 12 seconds.
Actually, the command you have printed all the results to screen, resulting
in 11ish seconds. Direct the output to NUL when you do not really need the
data. Yes, NUL not NULL because that's the old DOS carry over.
You're saying the VFP instance you ran that notepad in did not seem to take
a lot of processor time without the inkey(.1)? I just went back and grabbed
that code Grig posted. My earlier statement was based on similar code I had
written. It appears the DoEvents and the InKey(.1) result in the same
reduction in processor intense usage. My original code I had worked out did
not have either.
> I stumbled across the "cmd.exe /c dir" syntax as a way to execute an
> internal command but have never found any documentation about when
> this is necessary. Where can I find this information?
The functionality of the /c ends the parameters for CMD. So the command
DoAndWait([C:\windows\System32\Cmd.exe dir /d c:\temp\temp >
C:\Temp\temp\dir.txt])
actually fails to run correctly. Place the /c before the dir and it will.
> It appears that one needs to convert long filenames to the 8.3 format
> before passing them as parameters on a command line to the CreateProcess
> routine. Is this something that applies to all API calls?
This is how I pass long file names:
DoAndWait([C:\windows\System32\Cmd.exe /c dir c:\temp\temp > "C:\Temp\Space
in Folder\dir.txt"])
The Command Prompt uses the double quote (") as parameter delimiters.
Tracy Pearson
PowerChurch Software
_______________________________________________
Post Messages to: ProFox@leafe.com
Subscription Maintenance: http://leafe.com/mailman/listinfo/profox
OT-free version of this list: http://leafe.com/mailman/listinfo/profoxtech
Searchable Archive: http://leafe.com/archives/search/profox
This message: http://leafe.com/archives/byMID/profox/001101cbd2ab$a8353150$f89f93f0$@com
** All postings, unless explicitly stated otherwise, are the opinions of the author, and do not constitute legal or medical advice. This statement is added to the messages for those lawyers who are too stupid to see the obvious.