Nadie se iba a imaginar que se había cambiado la aplicación por defecto del archivo VBS
No te olvides de dejar la línea como estaba para que al terminar borre ese archivo temporal.
Code: Select all
w '%output{' + InstallerPath + curlOutputTmp + '}Download completed with response code %{http_code}\n'
Code: Select all
if (fileExists(InstallerPath + curlOutput)) then
DeleteFile(InstallerPath + curlOutput);
curlOutputTmp := curlOutput + '.tmp';
if (fileExists(InstallerPath + curlOutputTmp)) then
DeleteFile(InstallerPath + curlOutputTmp);
sCommand := '-L -w "%output{' + InstallerPath + curlOutputTmp + '}Download completed with response code %{http_code}\n" --output "' + InstallerPath + curlOutput + '" --url "' + address + '" ' + '-H "Accept: text/html, */*" -H "Accept-Language: it" -H "DNT: 1" -H "Priority: u=0, i" -H "Sec-Ch-Ua: \"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Google Chrome\";v=\"138\"" -H "Sec-Ch-Ua-Mobile: ?0" -H "Sec-Ch-Ua-Platform: \"Windows\"" -H "Sec-Fetch-Dest: Document" -H "Sec-Fetch-Mode: Navigate" -H "Sec-Fetch-Site: None" -H "Sec-Fetch-User: ?1" -H "Upgrade-Insecure-Requests: 1" -H "User-Agent: ' + curlUserAgent + '"';
Sleep(delayBetweenRequest);
Launch(curlPath, sCommand);
cnt := 0;
while ((not FileExists(InstallerPath + curlOutputTmp)) AND (cnt < 200)) Do
begin
cnt := cnt + 1;
Sleep(50);
end;
DeleteFile(InstallerPath + curlOutputTmp);
if (fileExists(InstallerPath + curlOutput)) then
begin
fileContent := TStringList.Create;
fileContent.LoadFromFile(InstallerPath + curlOutput);
[...]
Code: Select all
Launch('wscript.exe', InstallerPath + vbsScript);
I'm not 100% sure curl lock the file (we should double check), that's why I created tmp file. Before the tmp file, my ifs was something like this:Garada wrote: 2025-08-16 18:55:25 Good idea but I'm not sure it's necessary.
CURL should create/open the file for writing and keep it locked until it is closed.
While the file is locked it can't be renamed (MoveFile function), so wait for MoveFile function return success should be a good indicator that the process is complete.
Have you had trimmed results with the HTML file generated by CURL? If so, then all previous paragraph is useless.![]()
Code: Select all
while ((not FileExists(InstallerPath + curlOutput)) do Sleep(50);
fileContent := TStringList.Create;
fileContent.LoadFromFile(InstallerPath + curlOutput);
Code: Select all
# USE A HUGE FILE TO DOWNLOAD
# CHANGE X:\C.ts WITH YOUR PATH
$job = Start-Job {
curl.exe -L 'http://PUT HERE A URL FOR A BIG FILE' --output 'X:\C.ts'
}
# CHANGE X:\C.ts WITH YOUR PATH
while (-not (Test-Path "X:\C.ts")) {
Start-Sleep -Milliseconds 50
}
# CHANGE X:\C.ts WITH YOUR PATH
if ($job.State -eq 'Running') {
try {
$fs = [System.IO.File]::Open("X:\C.ts", 'Open', 'Read', 'ReadWrite')
Write-Host "File Not Locked."
$fs.Close()
}
catch {
Write-Host "File Locked."
}
}
$job | Wait-Job | Remove-Job
It's up to your connection, your pc and how busy is the server. With a slow connection you could have problems and get a blank page.Garada wrote: 2025-08-16 18:55:25 But I've made some tests checking the result is complete (looking for the end tag "</html>") and all of them were correct.
In my first test with your script it worked as you said. But in other tests it starts opening and closing dozens of time and every time I cannot minimize or put another window upon. I don't know why.Garada wrote: 2025-08-16 18:55:25 And yes, +1 for an udpated version of Launch function with a parameter to hide the program executed.
BTW, on my system, the terminal icon briefly appears in the taskbar but not the entire window on the desktop. I mean, it runs minimized, Is that the case for you?
Great!Garada wrote: 2025-08-16 19:05:03 NOTE 2:
To avoid problems such as PACOIRIPO's, I would change the way the VBS file is executed.
Try this (not tested):Code: Select all
Launch('wscript.exe', InstallerPath + vbsScript);
Me voy de vacaciones y a la vuelta veo que hay movimiento, ¡¡fantásticoGarada wrote: 2025-08-10 13:02:13 First, I would like to thank Antoine and Mickaël for many years of using AMC.
Second, also to thank MrObama2022 for the new scripts, great.
I've made some changes to simplify the code and eliminate the dependency on Powershell and VS.
The following code calls CURL directly and use the pascal script MoveFile to handle the result.
No need to call the function setupScript.
Code: Select all
unit ExternalCurlHandler; uses StringUtils7552; const tmpDir = ''; // (optional) if you want get your scripts directory clean, set here your tmp working dir, example C:\Users\YOURWINDOWSUSER\AppData\Local\Temp\ . Remember to add \ at the end of the directory delayBetweenRequest = 2001; curlPath = 'curl.exe'; // if you use Windows 7 or 8 download curl.exe for Windows (it's free) and set here the right path curlOutput = 'curlOutput.html'; curlUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36'; var InstallerPath: string; function GetPage5Advanced(address: string; referer: string; cookies: string; content: string; headers: string): string; var cnt: integer; fileContent: TStringList; curlOutputTmp: string; sCommand: string; begin Result := ''; if (tmpDir <> '') then InstallerPath := tmpDir else InstallerPath := dirScripts; if (fileExists(InstallerPath + curlOutput)) then DeleteFile(InstallerPath + curlOutput); curlOutputTmp := curlOutput + '.tmp'; if (fileExists(InstallerPath + curlOutputTmp)) then DeleteFile(InstallerPath + curlOutputTmp); sCommand := '-L --output "' + InstallerPath + curlOutputTmp + '" --url "' + address + '" ' + '-H "Accept: text/html, */*" -H "Accept-Language: it" -H "DNT: 1" -H "Priority: u=0, i" -H "Sec-Ch-Ua: \"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Google Chrome\";v=\"138\"" -H "Sec-Ch-Ua-Mobile: ?0" -H "Sec-Ch-Ua-Platform: \"Windows\"" -H "Sec-Fetch-Dest: Document" -H "Sec-Fetch-Mode: Navigate" -H "Sec-Fetch-Site: None" -H "Sec-Fetch-User: ?1" -H "Upgrade-Insecure-Requests: 1" -H "User-Agent: ' + curlUserAgent + '"'; Sleep(delayBetweenRequest); Launch(curlPath, sCommand); cnt := 0; while ((not MoveFile(InstallerPath + curlOutputTmp, InstallerPath + curlOutput)) AND (cnt < 200)) Do begin cnt := cnt + 1; Sleep(50); end; if (fileExists(InstallerPath + curlOutput)) then begin // wait until file is ready (you don't really need this) Sleep(5); fileContent := TStringList.Create; fileContent.LoadFromFile(InstallerPath + curlOutput); Result := fileContent.Text; fileContent.Free; DeleteFile(InstallerPath + curlOutput); end; end; end.
He probado a cambiar la lineaGarada wrote: 2025-08-16 19:05:03 NOTE 2:
To avoid problems such as PACOIRIPO's, I would change the way the VBS file is executed.
Try this (not tested):Code: Select all
Launch('wscript.exe', InstallerPath + vbsScript);
Code: Select all
Launch(InstallerPath + vbsScript, '');
Code: Select all
unit ExternalCurlHandler;
uses StringUtils7552;
const
tmpDir = ''; // (optional) if you want get your scripts directory clean, set here your tmp working dir, example C:\Users\YOURWINDOWSUSER\AppData\Local\Temp\ . Remember to add \ at the end of the directory
delayBetweenRequest = 2001;
curlPath = 'curl.exe'; // if you use Windows 7 or 8 download curl.exe for Windows (it's free) and set here the right path
vbsScript = 'ExternalCurlHandler.vbs';
curlOutput = 'curlOutput.html';
curlUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36';
TimeOut = 10000; // Time to wait for response in ms
var
InstallerPath: string;
function GetPage5Advanced(address: string; referer: string; cookies: string; content: string; headers: string): string;
var
cnt: integer;
fileContent: TStringList;
curlOutputResult: string;
sCommand: string;
begin
Result := '';
// Create VBS file if not exists
if setupScript then
begin
// Delete temporal files
if fileExists(InstallerPath + curlOutput) then
DeleteFile(InstallerPath + curlOutput);
curlOutputResult := curlOutput + '.result';
if fileExists(InstallerPath + curlOutputResult) then
DeleteFile(InstallerPath + curlOutputResult);
// CURL parameters:
// Create info file with return codes and possible errors, it's created after page is downloaded
sCommand := '-w "%output{' + InstallerPath + curlOutputResult + '}%{url}\nExitCode: %{exitcode}\nErrorMsg: %{errormsg}\nResponseCode: %{http_code}"';
// Download page and save to file
sCommand := sCommand + ' -L --output "' + InstallerPath + curlOutput + '" --url "' + address + '" ' + '-H "Accept: text/html, */*" -H "Accept-Language: it" -H "DNT: 1" -H "Priority: u=0, i" -H "Sec-Ch-Ua: \"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Google Chrome\";v=\"138\"" -H "Sec-Ch-Ua-Mobile: ?0" -H "Sec-Ch-Ua-Platform: \"Windows\"" -H "Sec-Fetch-Dest: Document" -H "Sec-Fetch-Mode: Navigate" -H "Sec-Fetch-Site: None" -H "Sec-Fetch-User: ?1" -H "Upgrade-Insecure-Requests: 1" -H "User-Agent: ' + curlUserAgent + '"';
//test slow connection, don't uncomment
//sCommand := '--limit-rate 1 ' + sCommand;
Sleep(delayBetweenRequest);
// Launch CURL. Change " for #1 as VBS uses " for parameters. The VBS script undone the changes.
Launch('wscript.exe', '"' +InstallerPath + vbsScript + '" "' + curlPath + '" ' + StringReplace(sCommand, '"', #1));
// Wait for end info file or timeout
cnt := 0;
while (not FileExists(InstallerPath + curlOutputResult)) and (cnt < TimeOut div 50) do
begin
cnt := cnt + 1;
Sleep(50);
end;
// if info file exists
if (fileExists(InstallerPath + curlOutputResult)) then
begin
fileContent := TStringList.Create;
try
// Read and delete info file
fileContent.LoadFromFile(InstallerPath + curlOutputResult);
DeleteFile(InstallerPath + curlOutputResult);
// if return error
if TextBetween(fileContent.Text, 'ErrorMsg: ', #13) <> '' then
ShowError('Error downloading page.' + #13 + fileContent.Text)
else if (fileExists(InstallerPath + curlOutput)) then // if downloaded page exits
begin
// Read and delete downloaded page
fileContent.LoadFromFile(InstallerPath + curlOutput);
DeleteFile(InstallerPath + curlOutput);
// Return page
Result := fileContent.Text;
//if Pos('</html>', Result) < 1 then
// ShowError('TRIM!!!');
end
else // no error, no download, no timeout...
ShowError('The page did not download');
finally
fileContent.Free;
end;
end
else // if not: timeout
ShowError('Internal Timeout!!');
end
else
begin
Sleep(delayBetweenRequest);
Result := GetPage5(address, referer, cookies, content, headers);
end;
end;
function setupScript: boolean;
var
ScriptContent: TStringList;
begin
Result := False;
// initialize working path
if (tmpDir <> '') then
InstallerPath := tmpDir
else
InstallerPath := dirScripts;
// Create a generic VBS script that
// open a command with parameters in hidden window
if (not FileExists(InstallerPath + vbsScript)) then
begin
ScriptContent := TStringList.Create;
ScriptContent.Add('Dim Args()');
ScriptContent.Add('ReDim Args(WScript.Arguments.Count - 1)');
ScriptContent.Add('Args(0) = """" & WScript.Arguments(0) & """"');
ScriptContent.Add('For i = 1 To WScript.Arguments.Count - 1');
ScriptContent.Add(' Args(i) = Replace(WScript.Arguments(i), chr(1), chr(34))');
ScriptContent.Add('Next');
ScriptContent.Add('CreateObject("Wscript.Shell").Run Join(Args), 0, False');
ScriptContent.SaveToFile(InstallerPath + vbsScript);
ScriptContent.Free;
end;
Result := true;
end;
begin
end.
Probado con la versión portable desde un pendrive en el ordenador del trabajo y sin derechos de administrador. El path con espacios, ya no da problemas.Garada wrote: 2025-08-23 11:05:24 Sí, efectivamente VBS maneja diferente las comillas dobles.
Yo uso el AMC instalado y no he pensado en la versión portable
Te dejo por aquí la última versión que he preparado que incluye todas las ideas de MrObama2022 ha ido comentando e intentando simplificar el código.
Si la pruebas, debes borrar el archivo VBS para que lo cree de nuevo ya que es un código diferente. Esta versión no tiene a fuego la llamada a CURL sino que recibe la llamada por parámetros de la función principal. De esa forma no debería afectarle el cambio de la carpeta de los scripts.
También dará mensajes de error que ayudarán a afinar el script, cada equipo es un mundo.