jkuijt
November 30, 2024, 1:26pm
1
Hi all,
I have an “assets” folder with subfolders like:
C:\TEMP\assets
C:\TEMP\assets\css
C:\TEMP\assets\fonts
C:\TEMP\assets\js\
Now I would like to copy the complete “assets” folder C:\TEMP\assets*.* including all subfolders to:
%APPDATA%
So that I get:
%APPDATA%\assets
%APPDATA%\assets\css
%APPDATA%\assets\fonts
%APPDATA%\assets\js\
Is this possible with a default Clarion command? Or some smart piece of code?
Thank you and best regards
Jeffrey
jslarve
November 30, 2024, 3:01pm
2
I think you can get there with your old friend SHFileOperation, using FO_Copy.
Pretty sure the default is to recurse. SHFILEOPSTRUCTA (shellapi.h) - Win32 apps | Microsoft Learn
jkuijt
November 30, 2024, 3:22pm
3
Thank you Jeff!
I will try to figure out how to use this API in Clarion.
Best regards
Jeffrey
jslarve
November 30, 2024, 3:25pm
4
You do have to be careful with SHFileOperation to pass it correct parameters or bad things can happen, see the various comments on the MSDN page like …
Remarks
Important You must ensure that the source and destination paths are double-null terminated. A normal string ends in just a single null character. If you pass that value in either the source or destination members, the function will not realize when it has reached the end of the string and will continue to read on in memory until it comes to a random double null value. This can at least lead to a buffer overrun, and possibly the unintended deletion of unrelated data.
A simpler way might be to RUN() a DOS command either XCOPY or RoboCopy. PowerShell would be another. I like RoboCopy, but it does have a lot of switches. It can give you a log. AI can help.
jkuijt
November 30, 2024, 4:48pm
6
Thank you Carl!
I also like RoboCopy but don’t like the black splash window which the RUN command shows.
Best regards
Jeffrey
Have a look at Hide Command Prompt Window when RUN Batch file for ideas of how to hide the command window when you Run() a command.
jkuijt
November 30, 2024, 7:50pm
8
Thank you all, enough ideas.
Best regards
Jeffrey
Hi Jeffrey
Capesoft Oddjob does a great job of controlling and hiding running of batch files
and you get feedback into a variable,
which you can then display in your clarion window
regards
Johan
1 Like
Dirk1
December 1, 2024, 8:26am
10
Hi Jeffrey,
I use something like this
loc:FileName='cmd.exe'
loc:Parameters='/c robocopy "'&clip(glo:uncInstallatiepad)&'" "'&clip(loc:doelmap)&'" *.* /XF robocopy.* *.ini *.log /LEV:1 /Z /XA:SH /NDL /NJH /NJS /nc /ns /np /MT:8 /LOG:reserveprogramma.log'
if shellexecuteex_wacht(loc:FileName,,loc:Parameters,1,1)
message('Er is een fout opgetreden ('&runcode()&') bij kopieren van de programmabestanden. Zie reserveprogramma.log','Fout',ICON:Exclamation)
cycle
end
--------
shellexecuteex_wacht PROCEDURE (String pFile,<String pDirectory>,<String pParameters>,<Long pWait>,<Long pHide>) ! Declare Procedure
SHi LIKE(D_SHELLEXECUTEINFO)
new:File &CSTRING
new:Param &CSTRING
new:Directory &CSTRING
Verb long(0)
hProc UNSIGNED!LONG
lRetCode LONG
resultaat LONG
SEE_MASK_NOCLOSEPROCESS EQUATE(40h)
SEE_MASK_NOASYNC EQUATE(100h)
SEE_MASK_FLAG_NO_UI EQUATE(400h)
SW_SHOWNORMAL EQUATE(1)
INFINITE EQUATE(4294967295)
W WINDOW,AT(,,204,25),FONT('Arial',9,,),CENTER,ALRT(EscKey),ALRT(AltF4),GRAY,DOUBLE,MODAL
STRING('Externe programma is bezig, wachten aub...'),AT(7,7,195,10),USE(?String1),FONT(,,,FONT:bold)
END
CODE
new:file &= NEW CString(Len(Clip(pFile))+4) !+4 als met " en <0,0>
new:file = '"'&Clip(pFile)&'"'
If Not Omitted(pDirectory)
new:Directory &= NEW CSTRING(LEN(CLIP(makeunc(pDirectory)))+5)
new:Directory = '"'&clip(makeunc(pDirectory))&'"'
end
If Not Omitted(pParameters)
new:Param &= NEW CString(Len(pParameters)+3)
new:Param = '"'&clip(pParameters)&'"'!&'<0,0>'
End
CLEAR(shi)
shi.fMask = SEE_MASK_NOCLOSEPROCESS + SEE_MASK_NOASYNC
shi.hwnd = 0{PROP:Handle}
shi.lpVerb = ADDRESS(Verb)
shi.lpFile = ADDRESS(new:file)
shi.lpParameters = ADDRESS(new:Param)
shi.lpDirectory = ADDRESS(new:Directory)
if pHide
shi.nShow = 0
else
shi.nShow = SW_SHOWNORMAL
end
SHi.lpIDList = 0
shi.lpClass = 0
shi.hkeyClass = 0
shi.dwHotKey = 0
shi.DUMMYUNIONNAME = 0
shi.cbSize = SIZE(shi)
IF ShellExecuteEx(ADDRESS(shi))
hProc = shi.hProcess
else
hProc = 0
END
If hProc
If pWait
Open(W)
W{Prop:Timer} = 50
Accept
Case Event()
Of EVENT:Timer
if WaitForSingleObject(shi.hProcess,0)=0
I#= GetExitCodeProcess(hProc, lRetCode)
I# = CloseHandle(shi.hProcess)
W{PROP:Timer} = 0
End
close(W)
End !case
End!end accept loop
end!pwait
end!hproc
If Not(new:file &= NULL) !opschonen
Dispose(new:file)
End
if NOT(new:Directory &= NULL)
DISPOSE(new:Directory)
end
if NOT(new:Param &= NULL)
DISPOSE(new:Param)
end
RETURN(resultaat)
jkuijt
December 1, 2024, 8:46am
11
Hartelijk bedankt Dirk!
Thank you!
Best regards
Jeffrey
As I show in the below post if you run a batch file you can change the look so it looks a little better and not your typical DOS window.
If you’re going to use RoboCopy the RUN BAT file is an easy to get started. Once it works right then work on the look.
Please post your code when you get it working.
A simple idea is to make the DOS Window less visible. less obvious. or more like an App Window
Screen size small e.g. 60x10 … it can be smaller like 40x3
Colored White/Gray or like App. There are new ANSI colors in Win 10. Yu canot make both colors the same.
Prompt just space ($S) not X:>
Title not “Command Prompt” e.g. “Copying…”
MODE CON COLS=60 LINES=10
COLOR 87
PROMPT $S
TITLE Copying...
[image]
You could run the Batch file Minimized ma…
I would think Power Shell offers more options for changing the look.
RichCPT
December 2, 2024, 9:45pm
14
If you have CapeSoft’s WinEvent then you might try its “ds_CopyDirectory” function. It has an option to copy subfolders, too.
jkuijt
December 3, 2024, 4:10am
15
Thank you!
I will look at it.
Best regards
Jeffrey
Julian
December 5, 2024, 5:42pm
16
Late to the party again so I’m sure you’ll have cracked this by now, but as-per JSlarve’s suggestion, this I how I do it.
The last parameter is nice because it shows/hides the OS progress window.
jhTools.FileAPI_Copy Procedure(String inSourceFilename, String inTargetFilename,<BYTE inHideProgress>)
szSource CString(256)
szTarget CString(256)
FO_Copy Equate(2)
FOF_ALLOWUNDO Equate(040H)
FOF_NOCONFIRMATION Equate(010H)
FOF_No_UI EQUATE(0614H)
grp_SHFileOPStruct GROUP
hWnd Long
wFunc Long
pFrom Long
pTo Long
fFlags Long
fAnyOperationsAborted BYTE
hNameMappings Long
lpszProgressTitle LONG
.
Code
!-- Note: double NULL termination
szSource = Clip(inSourceFilename) & '<0><0>'
szTarget = Clip(inTargetFilename) & '<0><0>'
grp_SHFileOPStruct.hWnd = 0
grp_SHFileOPStruct.wFunc = FO_Copy
grp_SHFileOPStruct.pFrom = Address(szSource)
grp_SHFileOPStruct.pTo = Address(szTarget)
grp_SHFileOPStruct.fFlags = FOF_NOCONFIRMATION
!-- Hide Progress, ie: No GUI ?
if inHideProgress
grp_SHFileOPStruct.fFlags = FOF_NO_UI
.
!-- Create the folders in the target path..
!--
!SELF.CreateDirectoriesInPath(szTarget)
if SHFileOperation(Address(grp_SHFileOPStruct)) = 0 ! No Error
Return(True)
.
!-- Error..
Return(False)
`