Hello!
I would like to automate copying of all files in one document. Usually for files I use Copy /b name.txt name1.txt name2.txt Combined.txt on the command line. But Im tired of doing it manually, so Id like to add the "Merge to one text file" command in the context of the selected files. To do this, I need to get the names of the selected files, the question is how to do it better? GetOpenFileName function is not very suitable for this task. How can i get selected files in Windows Explorer using WinApi functions ?!
Best regards
Quote from: LiaoMi on August 19, 2017, 08:51:11 PM
How can i get selected files in Windows Explorer using WinApi functions ?!
A little involving from ASM, but a piece of cake for the script kiddies. ;)
You need to create a new file and keep appending the rest to it. Depending on what the file names are, you could do a *.* type file pattern for say "all TXT files" in a directory with "*.txt" or any predictable combination.
The API calls are FindFirstFile and FindNextFile.
Isn't Windows simple and easy to use?
Get selected items of folder with WinAPI (https://stackoverflow.com/questions/3382946/get-selected-items-of-folder-with-winapi/3400348#3400348)
However, you could throw the attached exe into the SendTo folder. Here is the source; GetFiles CL translates the dragged files into a string array:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi="Files_"+Replace$(fDate$(0), ".", 0))
Let esi=esi+"_"+Replace$(fTime$(0), ":", 0)+".txt" ; e.g. Files_190817_155907.txt
GetFiles CL
; SortFiles ; activate to put most recent first
For_ ecx=0 To Min(99, eax-1)
PrintLine Str$(GfSize(ecx)), Tb$, GfDate$(ecx), Spc2$, GfTime$(ecx), Tb$, Files$(ecx)
Next
void Str$("Combine %i files to single file:", Files$(?))
Let esi=Input$(eax, esi)
.if Instr_(esi, ".")
PrintLine Str$("writing %i textfiles to ", Files$(?)), esi
Open "O", 1, esi
For_ ecx=0 To Files$(?)-1
mov edi, Files$(ecx)
Print 1, FileRead$(edi), CrLf$, String$(40, "-."), CrLf$ ; decoration added ;-)
Next
Close
Inkey "See the result (y)?"
If_ eax=="y" Then ShEx esi
.else
Print "CANCELLED"
Delay 2000
.endif
EndOfCode
For easy testing, the attached source has OPT_Arg1 with three Masm32 SDK files. Of course, the -.-.-. decoration should be taken away if you don't need it. As usual, dragging true Unicode filenames is allowed, see screenshot below. "Invia a" is "Send to" in Italian.
Quote from: hutch-- on August 19, 2017, 10:49:30 PM
You need to create a new file and keep appending the rest to it. Depending on what the file names are, you could do a *.* type file pattern for say "all TXT files" in a directory with "*.txt" or any predictable combination.
The API calls are FindFirstFile and FindNextFile.
This is an alternative solution for the command line, you can drag and drop on the exe, getting all the names and then doing the merging. The question is how to get names!
Quote from: jj2007 on August 19, 2017, 10:55:14 PM
Isn't Windows simple and easy to use?
Get selected items of folder with WinAPI (https://stackoverflow.com/questions/3382946/get-selected-items-of-folder-with-winapi/3400348#3400348)
Very interesting, I think that a bit tricky solution.
Quote from: jj2007 on August 19, 2017, 10:55:14 PM
However, you could throw the attached exe into the SendTo folder. Here is the source; GetFiles CL translates the dragged files into a string array:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi="Files_"+Replace$(fDate$(0), ".", 0))
Let esi=esi+"_"+Replace$(fTime$(0), ":", 0)+".txt" ; e.g. Files_190817_155907.txt
GetFiles CL
; SortFiles ; activate to put most recent first
For_ ecx=0 To Min(99, eax-1)
PrintLine Str$(GfSize(ecx)), Tb$, GfDate$(ecx), Spc2$, GfTime$(ecx), Tb$, Files$(ecx)
Next
void Str$("Combine %i files to single file:", Files$(?))
Let esi=Input$(eax, esi)
.if Instr_(esi, ".")
PrintLine Str$("writing %i textfiles to ", Files$(?)), esi
Open "O", 1, esi
For_ ecx=0 To Files$(?)-1
mov edi, Files$(ecx)
Print 1, FileRead$(edi), CrLf$, String$(40, "-."), CrLf$ ; decoration added ;-)
Next
Close
Inkey "See the result (y)?"
If_ eax=="y" Then ShEx esi
.else
Print "CANCELLED"
Delay 2000
.endif
EndOfCode
For easy testing, the attached source has OPT_Arg1 with three Masm32 SDK files. Of course, the -.-.-. decoration should be taken away if you don't need it. As usual, dragging true Unicode filenames is allowed, see screenshot below. "Invia a" is "Send to" in Italian.
Very cool :icon_exclaim:, I didnt think about the SendTo option, and the Hutch solution will work too. Meanwhile, I was advised to look at the source 7zip https://sourceforge.net/projects/sevenzip/files/7-Zip/17.00/7z1700-src.7z/download (https://sourceforge.net/projects/sevenzip/files/7-Zip/17.00/7z1700-src.7z/download) Since the program registers the Schell Extension to receive files for compression. Most likely the method is more massive, not as simple as with SendTo. I have not yet found the code responsible for this processing. jj2007 thanks, with the source code, everything is ready, just like a mega service! :redface: It is very convenient now to work with files.
It very much depends on how you wish to access the file names, large numbers with predictable extensions OR filename parts are best done from the command line but if you want a UI, then you will be dragging and dropping the files into an interface where the names are accumulated in the order they are dropped unless you want to sort the name list. A list box would be very useful in this context, whatever is dropped into the interface gets added to the list box.
I have another Sendto solution:
Make a batch file:
echo off
for %%i in (%*) do type "%%~i">>c:\combined.txt
give it a name and copy it to the Sendto folder.
:badgrin:
Improved Sendto batch file, which accepts destination name:
@echo off
setlocal EnableDelayedExpansion
set mycommand=copy
for %%i in (%*) do (
set mycommand=!mycommand! "%%i" +
)
set /p dest="Enter destination file: "
set mycommand=!mycommand:~0,-2! %dest%
!mycommand!
If it can be done by a user specified file pattern on the command line and it is a text based file, it can be done like this.
Just read back and its very similar to AW's 1st suggestion.
@echo off
:::: %1 is a command line file pattern -> *.txt
:::: %2 is the target file name for the result.
for %%9 in (%1) do type %%9 >> %2
pause
Useage like this.
MyBatch *.txt combined.txt
Quote from: hutch-- on August 20, 2017, 12:56:07 AMA list box would be very useful in this context, whatever is dropped into the interface gets added to the list box.
Right :t
GuiParas equ "Combine text files: drag files to add", x50, y50, w300, h600 ; OPT_Icon Disk
include \masm32\MasmBasic\Res\MbGui.asm
invoke SetWindowPos, hWnd, HWND_TOPMOST, eax, eax, eax, eax, SWP_NOMOVE or SWP_NOSIZE
SetGlobals dest$, item$
GuiControl Edit, "edit", "~TmpFile.txt", h0+20, w800
GuiControl Ok, "button", "ok", h0+20, x800, w200
GuiControl MyBox, "listbox", y0+22, h1000-22
Let item$=New$(1000) ; event dropfiles yields UTF8, so we'll be generous
Event Menu
.if MenuID==Ok
Let dest$=Win$(hEdit)
MsgBox 0, Cat$("Copy files into"+CrLf$+dest$), "Hi", MB_YESNO
.if eax==IDYES
Open "O", #1, dest$
Print #1, Utf8Bom
For_ ct=0 To rv(SendMessage, hMyBox, LB_GETCOUNT, 0, 0)-1
invoke SendMessage, hMyBox, LB_GETTEXT, ct, item$
Print #1, FileRead$(item$), CrLf$, String$(40, "-."), CrLf$ ; decoration added ;-)
Next
Close
MsgBox 0, Cat$("Open "+dest$+" in the default application?"), "Hi", MB_YESNO
If_ eax==IDYES Then ShEx dest$
.endif
.endif
Event DropFiles
SetListbox Files$()
GuiEndNote there is a limit somewhere, AFAIK 32k for the total amount of paths passed while dragging.
Hello,
thanks for the very elegant solutions, these methods are the simplest among others, which I also found, even a batch file is enough :t
Getting the current selection from an Explorer window https://blogs.msdn.microsoft.com/oldnewthing/20130422-00/?p=4593 (https://blogs.msdn.microsoft.com/oldnewthing/20130422-00/?p=4593)
Querying information from an Explorer window https://blogs.msdn.microsoft.com/oldnewthing/20040720-00/?p=38393 (https://blogs.msdn.microsoft.com/oldnewthing/20040720-00/?p=38393)
I wish everyone a good Sunday :exclaim: