*script updated below to reflect suggested changes
This is a CMD script my main question is for PS(But would def take cmd advice too, it is working though). It's using a powershell command as a one liner to "extract" an embedded files from itself. (When you drag/drop files onto it, it will embed them into itself, double click the script to extract the embedded files)
The extract command is slow.. I just updated this and it used to have temp files but I was able to get both variables I needed by switching groups with the same regex once for the first variable and again for the second, so maybe there's a way to get them both without searching through the entire file for each one?
(UPDATED 7/13/23) Here is the full script BAG.cmd
@ECHO OFF & SET N=0
>nul 2>&1 REG ADD HKCU\Software\Classes\.Admin\shell\runas\command /f /ve /d "CMD /x /d /r SET \"f0=%%2\"& call \"%%2\" %%3"& SET _= %*
>nul 2>&1 FLTMC|| IF "%f0%" NEQ "%~f0" (CD.>"%temp%\runas.Admin" & START "%~n0" /high "%temp%\runas.Admin" "%~f0" "%_:"=""%" & EXIT /b)
>nul 2>&1 REG DELETE HKCU\Software\Classes\.Admin\ /f
>nul 2>&1 DEL %temp%\runas.Admin /f
FOR /F "usebackq skip=2 tokens=3-4" %%i IN (`REG QUERY "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v ProductName 2^>nul`) DO SET "VER=%%i %%j"
IF NOT "%VER%"=="Windows 10" ECHO. & ECHO UNSUPPORTED SYSTEM DETECTED! & ECHO. & PAUSE & EXIT
IF [%1]==[] (CALL :EMPTYBAG) ELSE (ECHO FILLING BAG... & ECHO. & FOR %%i IN (%*) DO (CALL :FILLBAG %%i))
IF %N%==1 (ECHO. & PAUSE & EXIT) ELSE (EXIT)
:FILLBAG
IF EXIST %1\* ECHO [Folder - Ignored] - %~nx1 - Folders are not supported! & SET N=1 & EXIT /b
IF %~z1 LSS 1 ECHO [File - Ignored] - %~nx1 - Empty files are not supported! & SET N=1 & EXIT /b
IF %~z1 GEQ 750000000 ECHO [File - Ignored] - %~nx1 - Not Added! The file is too large! & SET N=1 & EXIT /b
SET /A Size=(%~z0 + %~z1) * (130 / 100)
IF %Size% GEQ 980000000 ECHO [File - Ignored] - %~nx1 - Not Added! There is not enough room in the BAG! & SET N=1 & EXIT /b
ECHO.>>"%~f0" & POWERSHELL -nop -c "Add-Content '%~f0' "^""::%~nx1::"^"" -NoNewline; [Convert]::ToBase64String([IO.File]::ReadAllBytes("^""%~1"^"")) | Add-Content "^""%~f0"^"" -NoNewline; Add-Content '%~f0' "^""::%~nx1::"^"" -NoNewline" & DEL /F "%~1">nul
EXIT /b
:EMPTYBAG
IF %~z0 LSS 2205 ECHO The BAG is already empty, drag-and-drop something onto the BAG to put it inside. ;^) & ECHO. & PAUSE & EXIT /b
IF %~z0 GEQ 80000000 (ECHO EMPTYING BAG... ^(This may take a while^)) ELSE (ECHO EMPTYING BAG...)
POWERSHELL -nop -c "$file=Get-Content '%~f0'; $match=[regex]::Matches($file,'::([^^:]+)::(.+?)::\1::') | Foreach-Object {$name=$_.Groups[1].Value; $fname=$name; while(Test-Path -Path "^""%~dp0$fname"^"") { $n++; $fname="^""($n)$name"^"" }; $data=$_.Groups[2].Value; [IO.File]::WriteAllBytes("^""$fname"^"", [Convert]::FromBase64String($data))}; (Get-Content '%~f0' -TotalCount 22) | Set-Content '%~f0'">nul
EXIT /b
The original line that took such a long time was the extraction command (updated above):
POWERSHELL -nop -c $file=Get-Content '%~f0'; $name=[regex]::Match^($file,'\:\:^([^^^\:]+^)\:\:^(.+?^)\:\:\1\:\:'^).Groups[1].Value.Replace^('::',''^).Trim^(^); $data=[regex]::Match^($file,'\:\:^([^^^\:]+^)\:\:^(.+?^)\:\:\1\:\:'^).Groups[2].Value.Replace^('::',''^).Trim^(^); [IO.File]::WriteAllBytes(\"$name\", [Convert]::FromBase64String($data)); ^(get-content '%~f0' -totalcount 26^) ^| set-content '%~dp0emptyBAG.cmd' >nul
Embedding/Converting to B64 happens very quick, but extracting/converting back to whatever it was takes a while.
Ive tested up to 1gb file with this script, only takes about 30 seconds to embed, but that takes 7-8min to extract ;P
Probably a good size for a test case would be ~40mb to see the delay but not have it be too long.
I think I am rolling through the entire file 4 times during the extraction command, 1) to set the file to a var with Get-Content, 2) to scan the var for the first regex to set $name, 3) to scan the var for the second regex to set $data, and 4) to stream out the $data named $name to create the final file..
I dont know how to make it more efficient =/
**EDIT - Script is working properly now(updated above), TY to all who helped.