From 8793a51fc51e9523f72666072786c28c9458b54c Mon Sep 17 00:00:00 2001 From: Xavier Roche Date: Wed, 15 Jul 2026 15:27:20 +0200 Subject: [PATCH 1/7] Modernize the default User-Agent to the engine's honest identifier The GUI shipped a 1998 default UA string, "Mozilla/4.5 (compatible; HTTrack 3.0x; Windows 98)", and emitted it via -F for every new project, overriding the engine's own default. The engine (3.49-11) now defaults to an honest crawler identity, so align the GUI's new-project default with it. Only affects fresh projects; existing profiles keep their saved UserID. Co-Authored-By: Claude Opus 4.8 (1M context) --- WinHTTrack/Shell.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WinHTTrack/Shell.cpp b/WinHTTrack/Shell.cpp index fa65c0f..7a633b1 100755 --- a/WinHTTrack/Shell.cpp +++ b/WinHTTrack/Shell.cpp @@ -2855,7 +2855,7 @@ void Read_profile(CString path,int load_path) { maintab->m_option5.m_maxtime = MyGetProfileString(path,strSection, "MaxTime"); maintab->m_option4.m_timeout = MyGetProfileString(path,strSection, "TimeOut"); maintab->m_option4.m_rate = MyGetProfileString(path,strSection, "RateOut"); - maintab->m_option6.m_user = MyGetProfileString(path,strSection, "UserID","Mozilla/4.5 (compatible; HTTrack 3.0x; Windows 98)"); + maintab->m_option6.m_user = MyGetProfileString(path,strSection, "UserID","Mozilla/5.0 (compatible; HTTrack; +https://www.httrack.com/)"); maintab->m_option6.m_footer = MyGetProfileString(path,strSection, "Footer",HTS_DEFAULT_FOOTER); maintab->m_option6.m_accept_language = MyGetProfileString(path,strSection, "AcceptLanguage", default_lang); From e4a33386ed350828d3581255b6f7667f5a666967 Mon Sep 17 00:00:00 2001 From: Xavier Roche Date: Wed, 15 Jul 2026 15:36:22 +0200 Subject: [PATCH 2/7] Expose SOCKS5 proxy support in the GUI The engine (3.49-8+) accepts a scheme-prefixed proxy argument, -P socks5://[user:pass@]host[:port], and tunnels both HTTP and HTTPS origins through it automatically. The GUI had no way to select it. Add a "Proxy type" dropdown (HTTP / SOCKS5) to the advanced proxy Configure dialog, reusing the single existing proxy address/port/auth fields. The selection round-trips through COptionTab10::m_proxytype, persists as the ProxyType profile key, and the shell prepends the socks5:// scheme to the -P argument. HTTP stays the default, so the emitted command line is unchanged for existing projects. New LANG keys (LANG_PROXYTYPE, LANG_PROXYTYPETIP) are wired here; their translations are added engine-side in lang.def/lang/*.txt (see hand-over note). English display is covered by the .rc caption meanwhile. Co-Authored-By: Claude Opus 4.8 (1M context) --- WinHTTrack/OptionTab10.cpp | 3 +++ WinHTTrack/OptionTab10.h | 1 + WinHTTrack/ProxyId.cpp | 11 +++++++++++ WinHTTrack/ProxyId.h | 2 ++ WinHTTrack/Shell.cpp | 6 +++++- WinHTTrack/Shell.h | 2 +- WinHTTrack/WinHTTrack.rc | 26 ++++++++++++++------------ WinHTTrack/cpp_lang.h | 7 +++++++ WinHTTrack/resource.h | 4 +++- 9 files changed, 47 insertions(+), 15 deletions(-) diff --git a/WinHTTrack/OptionTab10.cpp b/WinHTTrack/OptionTab10.cpp index 64878d4..b40d529 100755 --- a/WinHTTrack/OptionTab10.cpp +++ b/WinHTTrack/OptionTab10.cpp @@ -44,6 +44,7 @@ COptionTab10::COptionTab10() : CPropertyPage(COptionTab10::IDD) m_port = _T(""); m_ftpprox = FALSE; //}}AFX_DATA_INIT + m_proxytype = 0; } COptionTab10::~COptionTab10() @@ -206,7 +207,9 @@ void COptionTab10::Onproxyconfigure() proxy.m_proxlogin=user_pass; proxy.m_proxpass=a+1; } + proxy.m_proxytype = m_proxytype; if (proxy.DoModal() == IDOK) { + m_proxytype = proxy.m_proxytype; if (proxy.m_proxlogin.GetLength()==0) { SetDlgItemTextCP(this, IDC_prox,proxy.m_proxadr); m_ctl_pwdhide.SetCheck(0); diff --git a/WinHTTrack/OptionTab10.h b/WinHTTrack/OptionTab10.h index 3a77fec..014d6d3 100644 --- a/WinHTTrack/OptionTab10.h +++ b/WinHTTrack/OptionTab10.h @@ -21,6 +21,7 @@ class COptionTab10 : public CPropertyPage const char* GetTip(int id); int modify; int prox_status; + int m_proxytype; /* 0 = HTTP proxy, 1 = SOCKS5 proxy */ char ProxyDetectBuff[16][1024]; CString ProxyDetectName[16]; diff --git a/WinHTTrack/ProxyId.cpp b/WinHTTrack/ProxyId.cpp index 9a80b82..cc6d366 100755 --- a/WinHTTrack/ProxyId.cpp +++ b/WinHTTrack/ProxyId.cpp @@ -28,6 +28,7 @@ CProxyId::CProxyId(CWnd* pParent /*=NULL*/) m_proxlogin = _T(""); m_proxpass = _T(""); m_proxport = _T(""); + m_proxytype = 0; //}}AFX_DATA_INIT } @@ -40,6 +41,8 @@ void CProxyId::DoDataExchange(CDataExchange* pDX) DDX_Text(pDX, IDC_proxlogin, m_proxlogin); DDX_Text(pDX, IDC_proxpass, m_proxpass); DDX_Text(pDX, IDC_proxport, m_proxport); + DDX_Control(pDX, IDC_proxytype, m_ctl_proxytype); + DDX_CBIndex(pDX, IDC_proxytype, m_proxytype); //}}AFX_DATA_MAP } @@ -61,9 +64,16 @@ BOOL CProxyId::OnInitDialog() SetIcon(httrack_icon,true); EnableToolTips(true); // TOOL TIPS SetForegroundWindow(); // yop en premier plan! + + /* Proxy protocol selector (HTTP or SOCKS5). Index maps to m_proxytype; + the scheme is prepended to the -P argument by the shell. */ + m_ctl_proxytype.AddString("HTTP"); + m_ctl_proxytype.AddString("SOCKS5"); + m_ctl_proxytype.SetCurSel(m_proxytype == 1 ? 1 : 0); if (LANG_T(-1)) { // Patcher en français SetWindowTextCP(this, LANG(LANG_R1)); + SetDlgItemTextCP(this, IDC_STATIC_ptype,LANG(LANG_PROXYTYPE)); SetDlgItemTextCP(this, IDC_STATIC_adr,LANG(LANG_R2)); SetDlgItemTextCP(this, IDC_STATIC_port,LANG(LANG_R3)); SetDlgItemTextCP(this, IDC_STATIC_auth,LANG(LANG_R4)); @@ -131,6 +141,7 @@ BOOL CProxyId::OnToolTipNotify( UINT id, NMHDR * pNMHDR, LRESULT * pResult ) const char* CProxyId::GetTip(int ID) { switch(ID) { + case IDC_proxytype: return LANG(LANG_PROXYTYPETIP); break; case IDC_proxadr: return LANG(LANG_R10); break; case IDC_proxport: return LANG(LANG_R11); break; case IDC_proxlogin: return LANG(LANG_R12); break; diff --git a/WinHTTrack/ProxyId.h b/WinHTTrack/ProxyId.h index 3bfe59d..389a11a 100644 --- a/WinHTTrack/ProxyId.h +++ b/WinHTTrack/ProxyId.h @@ -19,10 +19,12 @@ class CProxyId : public CDialog // Dialog Data //{{AFX_DATA(CProxyId) enum { IDD = IDD_ProxyId }; + CComboBox m_ctl_proxytype; CString m_proxadr; CString m_proxlogin; CString m_proxpass; CString m_proxport; + int m_proxytype; //}}AFX_DATA diff --git a/WinHTTrack/Shell.cpp b/WinHTTrack/Shell.cpp index 7a633b1..55e4d4d 100755 --- a/WinHTTrack/Shell.cpp +++ b/WinHTTrack/Shell.cpp @@ -587,6 +587,7 @@ void compute_options() { // proxy ShellOptions->proxy = maintab->m_option10.m_proxy; + ShellOptions->proxyscheme = (maintab->m_option10.m_proxytype == 1) ? "socks5://" : ""; ShellOptions->port = maintab->m_option10.m_port; if (maintab->m_option10.m_ftpprox) ShellOptions->proxyftp = "%f"; @@ -1998,7 +1999,7 @@ void lance(void) { if ((int)ShellOptions->proxy.GetLength()>0) { args.Add("-P"); - args.Add(ShellOptions->proxy + ":" + ShellOptions->port); + args.Add(ShellOptions->proxyscheme + ShellOptions->proxy + ":" + ShellOptions->port); } // mode spider, mettre après options @@ -2545,6 +2546,7 @@ void Write_profile(CString path,int load_path) { MyWriteProfileString(path,strSection, "WildCardFilters",maintab->m_option7.m_url2); MyWriteProfileString(path,strSection, "Proxy",maintab->m_option10.m_proxy); MyWriteProfileString(path,strSection, "Port",maintab->m_option10.m_port); + MyWriteProfileInt(path,strSection, "ProxyType",maintab->m_option10.m_proxytype); MyWriteProfileString(path,strSection, "Depth",maintab->m_option5.m_depth); MyWriteProfileString(path,strSection, "ExtDepth",maintab->m_option5.m_depth2); MyWriteProfileString(path,strSection, "MaxConn",maintab->m_option5.m_maxconn); @@ -2701,6 +2703,7 @@ void Write_profile(CString path,int load_path) { MyWriteProfileString(path,strSection,"Proxy",st); maintab->m_option10.GetDlgItemText(IDC_proxport,st); MyWriteProfileString(path,strSection,"Port",st); + MyWriteProfileInt(path,strSection,"ProxyType", maintab->m_option10.m_proxytype); n=maintab->m_option10.IsDlgButtonChecked(IDC_ftpprox); MyWriteProfileInt(path,strSection,"UseHTTPProxyForFTP", n); @@ -2873,6 +2876,7 @@ void Read_profile(CString path,int load_path) { // 10 maintab->m_option10.m_proxy = MyGetProfileString(path,strSection, "Proxy"); maintab->m_option10.m_port = MyGetProfileString(path,strSection, "Port"); + maintab->m_option10.m_proxytype = MyGetProfileInt(path,strSection, "ProxyType",0); maintab->m_option10.m_ftpprox = MyGetProfileInt(path,strSection, "UseHTTPProxyForFTP",1); // maintab->m_option5.m_depth = MyGetProfileString(path,strSection, "Depth"); diff --git a/WinHTTrack/Shell.h b/WinHTTrack/Shell.h index 96b0a29..f59e323 100755 --- a/WinHTTrack/Shell.h +++ b/WinHTTrack/Shell.h @@ -195,7 +195,7 @@ BOOL LaunchMirror(); /* Class */ class CShellOptions { public: - CString url, filelist, proxy, proxyftp, port, depth, + CString url, filelist, proxy, proxyscheme, proxyftp, port, depth, extdepth, get, where, meth, maxfile, max, frag, conn, tog, cache, robots, choixdeb, build, filtre, htmlfirst, index, index2, index_mail, dos, time, rate, hostquit, ka, diff --git a/WinHTTrack/WinHTTrack.rc b/WinHTTrack/WinHTTrack.rc index 60f328d..525d1da 100755 --- a/WinHTTrack/WinHTTrack.rc +++ b/WinHTTrack/WinHTTrack.rc @@ -425,22 +425,24 @@ BEGIN EDITTEXT IDC_STATIC_bo1,7,43,232,84,ES_MULTILINE | ES_READONLY | NOT WS_BORDER END -IDD_ProxyId DIALOG 0, 0, 266, 129 +IDD_ProxyId DIALOG 0, 0, 266, 145 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Proxy settings" FONT 8, "MS Sans Serif" BEGIN - EDITTEXT IDC_proxadr,104,8,141,12,ES_AUTOHSCROLL - EDITTEXT IDC_proxport,104,24,28,12,ES_AUTOHSCROLL | ES_NUMBER - EDITTEXT IDC_proxlogin,104,56,56,12,ES_AUTOHSCROLL - EDITTEXT IDC_proxpass,104,72,56,12,ES_PASSWORD | ES_AUTOHSCROLL - DEFPUSHBUTTON "OK",IDOK,208,104,50,14 - PUSHBUTTON "Cancel",IDCANCEL,8,104,50,14 - LTEXT "Proxy address:",IDC_STATIC_adr,8,8,83,10 - LTEXT "Proxy port:",IDC_STATIC_port,8,24,83,10 - LTEXT "Login:",IDC_STATIC_login,16,56,83,10 - LTEXT "Password:",IDC_STATIC_pass,16,72,83,10 - GROUPBOX "Authentication (only if needed)",IDC_STATIC_auth,8,40,248,48 + COMBOBOX IDC_proxytype,104,8,90,60,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + EDITTEXT IDC_proxadr,104,24,141,12,ES_AUTOHSCROLL + EDITTEXT IDC_proxport,104,40,28,12,ES_AUTOHSCROLL | ES_NUMBER + EDITTEXT IDC_proxlogin,104,72,56,12,ES_AUTOHSCROLL + EDITTEXT IDC_proxpass,104,88,56,12,ES_PASSWORD | ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,208,120,50,14 + PUSHBUTTON "Cancel",IDCANCEL,8,120,50,14 + LTEXT "Proxy type:",IDC_STATIC_ptype,8,10,90,10 + LTEXT "Proxy address:",IDC_STATIC_adr,8,26,90,10 + LTEXT "Proxy port:",IDC_STATIC_port,8,42,90,10 + LTEXT "Login:",IDC_STATIC_login,16,72,83,10 + LTEXT "Password:",IDC_STATIC_pass,16,88,83,10 + GROUPBOX "Authentication (only if needed)",IDC_STATIC_auth,8,56,248,48 END IDD_NewProj DIALOG 0, 0, 322, 181 diff --git a/WinHTTrack/cpp_lang.h b/WinHTTrack/cpp_lang.h index eec133d..bcd5004 100644 --- a/WinHTTrack/cpp_lang.h +++ b/WinHTTrack/cpp_lang.h @@ -464,6 +464,13 @@ #define LISTDEF_10 LANGSEL("LISTDEF_10") #define LISTDEF_11 LANGSEL("LISTDEF_11") +/* Strings for options exposed from the engine (post 3.49-2). + The English/translated values live in the engine's lang.def + lang/*.txt; + see the hand-over note. Until those ship, English users fall back to the + .rc captions and other languages show these keys empty (no crash). */ +#define LANG_PROXYTYPE LANGSEL("LANG_PROXYTYPE") +#define LANG_PROXYTYPETIP LANGSEL("LANG_PROXYTYPETIP") + #endif diff --git a/WinHTTrack/resource.h b/WinHTTrack/resource.h index d2e420a..39656ba 100644 --- a/WinHTTrack/resource.h +++ b/WinHTTrack/resource.h @@ -506,6 +506,8 @@ #define IDC_mime8 1306 #define IDC_other_headers 1306 #define IDC_default_referer 1308 +#define IDC_proxytype 1309 +#define IDC_STATIC_ptype 1310 #define ID_MENUITEM32771 32771 #define ID_MENUITEM32772 32772 #define ID_EXIT 32772 @@ -577,7 +579,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 247 #define _APS_NEXT_COMMAND_VALUE 32837 -#define _APS_NEXT_CONTROL_VALUE 1309 +#define _APS_NEXT_CONTROL_VALUE 1311 #define _APS_NEXT_SYMED_VALUE 108 #endif #endif From e57cf5d4ae60f40fc0b1c8d2ff9e54b7264cb68a Mon Sep 17 00:00:00 2001 From: Xavier Roche Date: Wed, 15 Jul 2026 15:41:15 +0200 Subject: [PATCH 3/7] Expose --cookies-file (preload a cookies.txt) on the Spider tab The engine (3.49-10) can preload a Netscape cookies.txt before crawling. Add a "Load cookies from file" path field to the Spider tab, persist it as the CookiesFile profile key, and emit --cookies-file when set. LANG keys LANG_COOKIEFILE / LANG_COOKIEFILETIP are wired; translations follow engine-side (hand-over note). Co-Authored-By: Claude Opus 4.8 (1M context) --- WinHTTrack/OptionTab8.cpp | 4 ++++ WinHTTrack/OptionTab8.h | 1 + WinHTTrack/Shell.cpp | 11 +++++++++++ WinHTTrack/Shell.h | 3 ++- WinHTTrack/WinHTTrack.rc | 2 ++ WinHTTrack/cpp_lang.h | 2 ++ WinHTTrack/resource.h | 4 +++- 7 files changed, 25 insertions(+), 2 deletions(-) diff --git a/WinHTTrack/OptionTab8.cpp b/WinHTTrack/OptionTab8.cpp index 97598c1..2b3431c 100755 --- a/WinHTTrack/OptionTab8.cpp +++ b/WinHTTrack/OptionTab8.cpp @@ -34,6 +34,7 @@ COptionTab8::COptionTab8() : CPropertyPage(COptionTab8::IDD) m_toler = FALSE; m_updhack = FALSE; m_urlhack = FALSE; + m_cookiesfile = _T(""); //}}AFX_DATA_INIT } @@ -53,6 +54,7 @@ void COptionTab8::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_toler, m_toler); DDX_Check(pDX, IDC_updhack, m_updhack); DDX_Check(pDX, IDC_urlhack, m_urlhack); + DDX_Text(pDX, IDC_cookiesfile, m_cookiesfile); //}}AFX_DATA_MAP } @@ -104,6 +106,7 @@ BOOL COptionTab8::OnInitDialog() SetDlgItemTextCP(this, IDC_toler,LANG(LANG_I62)); SetDlgItemTextCP(this, IDC_updhack,LANG(LANG_I62b)); SetDlgItemTextCP(this, IDC_urlhack,LANG(LANG_I62b2)); + SetDlgItemTextCP(this, IDC_STATIC_cookiesfile,LANG(LANG_COOKIEFILE)); SetCombo(this,IDC_checktype,LISTDEF_7); SetCombo(this,IDC_robots,LISTDEF_8); } @@ -160,6 +163,7 @@ const char* COptionTab8::GetTip(int ID) case IDC_toler: return LANG(LANG_I1i); break; case IDC_updhack: return LANG(LANG_I1k); break; case IDC_urlhack: return LANG(LANG_I1k2); break; + case IDC_cookiesfile: return LANG(LANG_COOKIEFILETIP); break; } return ""; } diff --git a/WinHTTrack/OptionTab8.h b/WinHTTrack/OptionTab8.h index 865cbdb..34246e8 100644 --- a/WinHTTrack/OptionTab8.h +++ b/WinHTTrack/OptionTab8.h @@ -32,6 +32,7 @@ class COptionTab8 : public CPropertyPage BOOL m_toler; BOOL m_updhack; BOOL m_urlhack; + CString m_cookiesfile; //}}AFX_DATA diff --git a/WinHTTrack/Shell.cpp b/WinHTTrack/Shell.cpp index 55e4d4d..2ee6643 100755 --- a/WinHTTrack/Shell.cpp +++ b/WinHTTrack/Shell.cpp @@ -632,6 +632,7 @@ void compute_options() { if (maintab->m_option8.m_updhack) ShellOptions->updhack = "%s"; // update hack if (maintab->m_option8.m_urlhack) ShellOptions->urlhack = "%u"; // URL hack else ShellOptions->urlhack = "%u0"; + ShellOptions->cookiesfile = maintab->m_option8.m_cookiesfile; // store all in cache,logtype if(maintab->m_option9.m_Cache2!=0) ShellOptions->Cache2 = "k"; @@ -2001,6 +2002,12 @@ void lance(void) { args.Add("-P"); args.Add(ShellOptions->proxyscheme + ShellOptions->proxy + ":" + ShellOptions->port); } + + // preload extra cookies from a Netscape cookies.txt (--cookies-file) + if (ShellOptions->cookiesfile.GetLength() != 0) { + args.Add("--cookies-file"); + args.Add(ShellOptions->cookiesfile); + } // mode spider, mettre après options if (ShellOptions->choixdeb[0]=='!') { @@ -2513,6 +2520,7 @@ void Write_profile(CString path,int load_path) { MyWriteProfileInt(path,strSection, "TolerantRequests",maintab->m_option8.m_toler); MyWriteProfileInt(path,strSection, "UpdateHack",maintab->m_option8.m_updhack); MyWriteProfileInt(path,strSection, "URLHack",maintab->m_option8.m_urlhack); + MyWriteProfileString(path,strSection, "CookiesFile",maintab->m_option8.m_cookiesfile); MyWriteProfileInt(path,strSection, "StoreAllInCache",maintab->m_option9.m_Cache2); MyWriteProfileInt(path,strSection, "LogType",maintab->m_option9.m_logtype); MyWriteProfileInt(path,strSection, "UseHTTPProxyForFTP",maintab->m_option10.m_ftpprox); @@ -2693,6 +2701,8 @@ void Write_profile(CString path,int load_path) { MyWriteProfileInt(path,strSection, "UpdateHack", n); n=maintab->m_option8.IsDlgButtonChecked(IDC_urlhack); MyWriteProfileInt(path,strSection, "URLHack", n); + maintab->m_option8.GetDlgItemText(IDC_cookiesfile,st); + MyWriteProfileString(path,strSection, "CookiesFile", st); // 9 maintab->m_option9.GetDlgItemText(IDC_Cache2,st); MyWriteProfileString(path,strSection, "StoreAllInCache", st); @@ -2834,6 +2844,7 @@ void Read_profile(CString path,int load_path) { maintab->m_option8.m_toler = MyGetProfileInt(path,strSection, "TolerantRequests",0); maintab->m_option8.m_updhack = MyGetProfileInt(path,strSection, "UpdateHack",1); maintab->m_option8.m_urlhack = MyGetProfileInt(path,strSection, "URLHack",1); + maintab->m_option8.m_cookiesfile = MyGetProfileString(path,strSection, "CookiesFile"); maintab->m_option8.m_http10 = MyGetProfileInt(path,strSection, "HTTP10",0); maintab->m_option9.m_Cache2 = MyGetProfileInt(path,strSection, "StoreAllInCache",0); maintab->m_option9.m_logtype = MyGetProfileInt(path,strSection, "LogType",0); diff --git a/WinHTTrack/Shell.h b/WinHTTrack/Shell.h index f59e323..e437237 100755 --- a/WinHTTrack/Shell.h +++ b/WinHTTrack/Shell.h @@ -204,7 +204,8 @@ class CShellOptions { cookies, checktype, parsejava, Cache2, logtype, norecatch, toler, updhack, urlhack, http10, waittime, maxtime, maxrate, maxconn, maxlinks, hh, mm, ss, buff_filtres, buff_MIME, - _RasString, accept_language, other_headers, default_referer; + _RasString, accept_language, other_headers, default_referer, + cookiesfile; CString LINE_back; RASDIALPARAMS _dial; }; diff --git a/WinHTTrack/WinHTTrack.rc b/WinHTTrack/WinHTTrack.rc index 525d1da..8cebc2d 100755 --- a/WinHTTrack/WinHTTrack.rc +++ b/WinHTTrack/WinHTTrack.rc @@ -632,6 +632,8 @@ BEGIN CONTROL "URL hacks (join similar URLs)",IDC_urlhack,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,95,237,9 CONTROL "Tolerant requests (for servers)",IDC_toler,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,110,244,9 CONTROL "Force old HTTP/1.0 requests (no 1.1)",IDC_http10,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,125,237,9 + LTEXT "Load cookies from file:",IDC_STATIC_cookiesfile,16,144,120,8 + EDITTEXT IDC_cookiesfile,140,142,116,12,ES_AUTOHSCROLL END IDD_OPTION9 DIALOGEX 0, 0, 325, 143 diff --git a/WinHTTrack/cpp_lang.h b/WinHTTrack/cpp_lang.h index bcd5004..02957e6 100644 --- a/WinHTTrack/cpp_lang.h +++ b/WinHTTrack/cpp_lang.h @@ -470,6 +470,8 @@ .rc captions and other languages show these keys empty (no crash). */ #define LANG_PROXYTYPE LANGSEL("LANG_PROXYTYPE") #define LANG_PROXYTYPETIP LANGSEL("LANG_PROXYTYPETIP") +#define LANG_COOKIEFILE LANGSEL("LANG_COOKIEFILE") +#define LANG_COOKIEFILETIP LANGSEL("LANG_COOKIEFILETIP") #endif diff --git a/WinHTTrack/resource.h b/WinHTTrack/resource.h index 39656ba..c38ae51 100644 --- a/WinHTTrack/resource.h +++ b/WinHTTrack/resource.h @@ -508,6 +508,8 @@ #define IDC_default_referer 1308 #define IDC_proxytype 1309 #define IDC_STATIC_ptype 1310 +#define IDC_cookiesfile 1311 +#define IDC_STATIC_cookiesfile 1312 #define ID_MENUITEM32771 32771 #define ID_MENUITEM32772 32772 #define ID_EXIT 32772 @@ -579,7 +581,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 247 #define _APS_NEXT_COMMAND_VALUE 32837 -#define _APS_NEXT_CONTROL_VALUE 1311 +#define _APS_NEXT_CONTROL_VALUE 1313 #define _APS_NEXT_SYMED_VALUE 108 #endif #endif From 332d74bd462edc1906f096bfb9c2171b8d7992c4 Mon Sep 17 00:00:00 2001 From: Xavier Roche Date: Wed, 15 Jul 2026 15:43:35 +0200 Subject: [PATCH 4/7] Expose --pause (random delay between files) on the Flow Control tab The engine (3.49-10) can space out downloads by a random per-file delay. Add a "Pause between files" field (MIN[:MAX] seconds) to the Flow Control tab, persist it as PauseFiles, and emit --pause when set. This is distinct from the pre-existing -G pause-after-N-bytes throttle on Limits. LANG keys LANG_PAUSEFILES / LANG_PAUSEFILESTIP wired; translations follow engine-side. Co-Authored-By: Claude Opus 4.8 (1M context) --- WinHTTrack/OptionTab4.cpp | 4 ++++ WinHTTrack/OptionTab4.h | 1 + WinHTTrack/Shell.cpp | 11 +++++++++++ WinHTTrack/Shell.h | 2 +- WinHTTrack/WinHTTrack.rc | 2 ++ WinHTTrack/cpp_lang.h | 2 ++ WinHTTrack/resource.h | 4 +++- 7 files changed, 24 insertions(+), 2 deletions(-) diff --git a/WinHTTrack/OptionTab4.cpp b/WinHTTrack/OptionTab4.cpp index c1bb891..799f31b 100755 --- a/WinHTTrack/OptionTab4.cpp +++ b/WinHTTrack/OptionTab4.cpp @@ -33,6 +33,7 @@ COptionTab4::COptionTab4() : CPropertyPage(COptionTab4::IDD) m_rems = FALSE; m_rate = _T(""); m_ka = FALSE; + m_pausefiles = _T(""); //}}AFX_DATA_INIT } @@ -51,6 +52,7 @@ void COptionTab4::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_rems, m_rems); DDX_Text(pDX, IDC_rate, m_rate); DDX_Check(pDX, IDC_ka, m_ka); + DDX_Text(pDX, IDC_pausefiles, m_pausefiles); //}}AFX_DATA_MAP } @@ -79,6 +81,7 @@ BOOL COptionTab4::OnInitDialog() SetDlgItemTextCP(this, IDC_rems,LANG(LANG_I47)); // "Abandon hote si lent"); SetDlgItemTextCP(this, IDC_ka,LANG(LANG_I47e)); SetDlgItemTextCP(this, IDC_STATIC_timeout,LANG_I47d); // TimeOut(s) + SetDlgItemTextCP(this, IDC_STATIC_pausefiles,LANG(LANG_PAUSEFILES)); } return TRUE; // return TRUE unless you set the focus to a control @@ -131,6 +134,7 @@ const char* COptionTab4::GetTip(int ID) case IDC_rate: return LANG(LANG_I15); break; // "Minimum transfer rate tolerated","Taux de transfert minimal toléré"); break; case IDC_rems: return LANG(LANG_I16); break; // "Cancel all links from a host if it is too slow","Annuler tous les liens sur un domaine en cas de transfert trop lent"); break; case IDC_ka: return LANG(LANG_I47f); break; + case IDC_pausefiles: return LANG(LANG_PAUSEFILESTIP); break; } return ""; } diff --git a/WinHTTrack/OptionTab4.h b/WinHTTrack/OptionTab4.h index fac70c1..ad2e6cd 100644 --- a/WinHTTrack/OptionTab4.h +++ b/WinHTTrack/OptionTab4.h @@ -31,6 +31,7 @@ class COptionTab4 : public CPropertyPage BOOL m_rems; CString m_rate; BOOL m_ka; + CString m_pausefiles; //}}AFX_DATA diff --git a/WinHTTrack/Shell.cpp b/WinHTTrack/Shell.cpp index 2ee6643..aebafc3 100755 --- a/WinHTTrack/Shell.cpp +++ b/WinHTTrack/Shell.cpp @@ -633,6 +633,7 @@ void compute_options() { if (maintab->m_option8.m_urlhack) ShellOptions->urlhack = "%u"; // URL hack else ShellOptions->urlhack = "%u0"; ShellOptions->cookiesfile = maintab->m_option8.m_cookiesfile; + ShellOptions->pausefiles = maintab->m_option4.m_pausefiles; // store all in cache,logtype if(maintab->m_option9.m_Cache2!=0) ShellOptions->Cache2 = "k"; @@ -2008,6 +2009,12 @@ void lance(void) { args.Add("--cookies-file"); args.Add(ShellOptions->cookiesfile); } + + // random pause between files, MIN[:MAX] seconds (--pause) + if (ShellOptions->pausefiles.GetLength() != 0) { + args.Add("--pause"); + args.Add(ShellOptions->pausefiles); + } // mode spider, mettre après options if (ShellOptions->choixdeb[0]=='!') { @@ -2521,6 +2528,7 @@ void Write_profile(CString path,int load_path) { MyWriteProfileInt(path,strSection, "UpdateHack",maintab->m_option8.m_updhack); MyWriteProfileInt(path,strSection, "URLHack",maintab->m_option8.m_urlhack); MyWriteProfileString(path,strSection, "CookiesFile",maintab->m_option8.m_cookiesfile); + MyWriteProfileString(path,strSection, "PauseFiles",maintab->m_option4.m_pausefiles); MyWriteProfileInt(path,strSection, "StoreAllInCache",maintab->m_option9.m_Cache2); MyWriteProfileInt(path,strSection, "LogType",maintab->m_option9.m_logtype); MyWriteProfileInt(path,strSection, "UseHTTPProxyForFTP",maintab->m_option10.m_ftpprox); @@ -2703,6 +2711,8 @@ void Write_profile(CString path,int load_path) { MyWriteProfileInt(path,strSection, "URLHack", n); maintab->m_option8.GetDlgItemText(IDC_cookiesfile,st); MyWriteProfileString(path,strSection, "CookiesFile", st); + maintab->m_option4.GetDlgItemText(IDC_pausefiles,st); + MyWriteProfileString(path,strSection, "PauseFiles", st); // 9 maintab->m_option9.GetDlgItemText(IDC_Cache2,st); MyWriteProfileString(path,strSection, "StoreAllInCache", st); @@ -2845,6 +2855,7 @@ void Read_profile(CString path,int load_path) { maintab->m_option8.m_updhack = MyGetProfileInt(path,strSection, "UpdateHack",1); maintab->m_option8.m_urlhack = MyGetProfileInt(path,strSection, "URLHack",1); maintab->m_option8.m_cookiesfile = MyGetProfileString(path,strSection, "CookiesFile"); + maintab->m_option4.m_pausefiles = MyGetProfileString(path,strSection, "PauseFiles"); maintab->m_option8.m_http10 = MyGetProfileInt(path,strSection, "HTTP10",0); maintab->m_option9.m_Cache2 = MyGetProfileInt(path,strSection, "StoreAllInCache",0); maintab->m_option9.m_logtype = MyGetProfileInt(path,strSection, "LogType",0); diff --git a/WinHTTrack/Shell.h b/WinHTTrack/Shell.h index e437237..4852232 100755 --- a/WinHTTrack/Shell.h +++ b/WinHTTrack/Shell.h @@ -205,7 +205,7 @@ class CShellOptions { toler, updhack, urlhack, http10, waittime, maxtime, maxrate, maxconn, maxlinks, hh, mm, ss, buff_filtres, buff_MIME, _RasString, accept_language, other_headers, default_referer, - cookiesfile; + cookiesfile, pausefiles; CString LINE_back; RASDIALPARAMS _dial; }; diff --git a/WinHTTrack/WinHTTrack.rc b/WinHTTrack/WinHTTrack.rc index 8cebc2d..ffe9b70 100755 --- a/WinHTTrack/WinHTTrack.rc +++ b/WinHTTrack/WinHTTrack.rc @@ -518,6 +518,8 @@ BEGIN EDITTEXT IDC_rate,130,95,32,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "B/s",IDC_STATIC,170,95,17,8 CONTROL "Remove host if low",IDC_rems,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,130,109,183,10 + LTEXT "Pause between files:",IDC_STATIC_pausefiles,16,124,110,8 + EDITTEXT IDC_pausefiles,130,122,45,12,ES_AUTOHSCROLL END IDD_OPTION5 DIALOGEX 0, 0, 260, 198 diff --git a/WinHTTrack/cpp_lang.h b/WinHTTrack/cpp_lang.h index 02957e6..1e964ce 100644 --- a/WinHTTrack/cpp_lang.h +++ b/WinHTTrack/cpp_lang.h @@ -472,6 +472,8 @@ #define LANG_PROXYTYPETIP LANGSEL("LANG_PROXYTYPETIP") #define LANG_COOKIEFILE LANGSEL("LANG_COOKIEFILE") #define LANG_COOKIEFILETIP LANGSEL("LANG_COOKIEFILETIP") +#define LANG_PAUSEFILES LANGSEL("LANG_PAUSEFILES") +#define LANG_PAUSEFILESTIP LANGSEL("LANG_PAUSEFILESTIP") #endif diff --git a/WinHTTrack/resource.h b/WinHTTrack/resource.h index c38ae51..eb615ef 100644 --- a/WinHTTrack/resource.h +++ b/WinHTTrack/resource.h @@ -510,6 +510,8 @@ #define IDC_STATIC_ptype 1310 #define IDC_cookiesfile 1311 #define IDC_STATIC_cookiesfile 1312 +#define IDC_pausefiles 1313 +#define IDC_STATIC_pausefiles 1314 #define ID_MENUITEM32771 32771 #define ID_MENUITEM32772 32772 #define ID_EXIT 32772 @@ -581,7 +583,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 247 #define _APS_NEXT_COMMAND_VALUE 32837 -#define _APS_NEXT_CONTROL_VALUE 1313 +#define _APS_NEXT_CONTROL_VALUE 1315 #define _APS_NEXT_SYMED_VALUE 108 #endif #endif From bf7646dfefb1523d58e9e48a6c67bb0204c901f8 Mon Sep 17 00:00:00 2001 From: Xavier Roche Date: Wed, 15 Jul 2026 15:46:49 +0200 Subject: [PATCH 5/7] Expose the URL-hack opt-out toggles on the Links tab The engine (3.49-10) split the -%u URL-hack into independently disableable parts. Add three checkboxes to the Links tab (keep www. prefix / keep double slashes / keep query order) that emit --keep-www-prefix, --keep-double-slashes and --keep-query-order, persisted as KeepWww / KeepSlashes / KeepQueryOrder. All default off, so the emitted command line is unchanged unless the user opts out. LANG keys and tooltips wired; translations follow engine-side. Co-Authored-By: Claude Opus 4.8 (1M context) --- WinHTTrack/OptionTab1.cpp | 18 ++++++++++++++++++ WinHTTrack/OptionTab1.h | 3 +++ WinHTTrack/Shell.cpp | 20 ++++++++++++++++++++ WinHTTrack/Shell.h | 2 +- WinHTTrack/WinHTTrack.rc | 5 ++++- WinHTTrack/cpp_lang.h | 6 ++++++ WinHTTrack/resource.h | 5 ++++- 7 files changed, 56 insertions(+), 3 deletions(-) diff --git a/WinHTTrack/OptionTab1.cpp b/WinHTTrack/OptionTab1.cpp index 6a1426d..7a165ec 100755 --- a/WinHTTrack/OptionTab1.cpp +++ b/WinHTTrack/OptionTab1.cpp @@ -30,6 +30,9 @@ COptionTab1::COptionTab1() : CPropertyPage(COptionTab1::IDD) m_parseall = FALSE; m_testall = FALSE; m_htmlfirst = FALSE; + m_keepwww = FALSE; + m_keepslashes = FALSE; + m_keepqueryorder = FALSE; //}}AFX_DATA_INIT } @@ -45,6 +48,9 @@ void COptionTab1::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_parseall, m_parseall); DDX_Check(pDX, IDC_testall, m_testall); DDX_Check(pDX, IDC_htmlfirst, m_htmlfirst); + DDX_Check(pDX, IDC_keepwww, m_keepwww); + DDX_Check(pDX, IDC_keepslashes, m_keepslashes); + DDX_Check(pDX, IDC_keepqueryorder, m_keepqueryorder); //}}AFX_DATA_MAP } @@ -69,11 +75,17 @@ BOOL COptionTab1::OnInitDialog() GetDlgItem(IDC_link) ->ModifyStyle(0,WS_DISABLED); GetDlgItem(IDC_testall) ->ModifyStyle(0,WS_DISABLED); GetDlgItem(IDC_htmlfirst)->ModifyStyle(0,WS_DISABLED); + GetDlgItem(IDC_keepwww) ->ModifyStyle(0,WS_DISABLED); + GetDlgItem(IDC_keepslashes)->ModifyStyle(0,WS_DISABLED); + GetDlgItem(IDC_keepqueryorder)->ModifyStyle(0,WS_DISABLED); } else { GetDlgItem(IDC_parseall) ->ModifyStyle(WS_DISABLED,0); GetDlgItem(IDC_link) ->ModifyStyle(WS_DISABLED,0); GetDlgItem(IDC_testall) ->ModifyStyle(WS_DISABLED,0); GetDlgItem(IDC_htmlfirst)->ModifyStyle(WS_DISABLED,0); + GetDlgItem(IDC_keepwww) ->ModifyStyle(WS_DISABLED,0); + GetDlgItem(IDC_keepslashes)->ModifyStyle(WS_DISABLED,0); + GetDlgItem(IDC_keepqueryorder)->ModifyStyle(WS_DISABLED,0); } // Patcher l'interface pour les Français ;-) @@ -83,6 +95,9 @@ BOOL COptionTab1::OnInitDialog() SetDlgItemTextCP(this, IDC_testall,LANG(LANG_I32)); // "Tester tous les liens (même ceux interdits)"); SetDlgItemTextCP(this, IDC_parseall,LANG(LANG_I32b)); SetDlgItemTextCP(this, IDC_htmlfirst,LANG(LANG_I32c)); + SetDlgItemTextCP(this, IDC_keepwww,LANG(LANG_KEEPWWW)); + SetDlgItemTextCP(this, IDC_keepslashes,LANG(LANG_KEEPSLASHES)); + SetDlgItemTextCP(this, IDC_keepqueryorder,LANG(LANG_KEEPQUERYORDER)); } return TRUE; // return TRUE unless you set the focus to a control @@ -131,6 +146,9 @@ const char* COptionTab1::GetTip(int ID) case IDC_testall: return LANG(LANG_I2); break; // "Test all links in pages","Tester tous les liens dans les pages"); break; case IDC_parseall: return LANG(LANG_I2b); break; case IDC_htmlfirst: return LANG(LANG_I2c); break; + case IDC_keepwww: return LANG(LANG_KEEPWWWTIP); break; + case IDC_keepslashes: return LANG(LANG_KEEPSLASHESTIP); break; + case IDC_keepqueryorder: return LANG(LANG_KEEPQUERYORDERTIP); break; } return ""; } diff --git a/WinHTTrack/OptionTab1.h b/WinHTTrack/OptionTab1.h index 3e1de36..5a99e77 100644 --- a/WinHTTrack/OptionTab1.h +++ b/WinHTTrack/OptionTab1.h @@ -28,6 +28,9 @@ class COptionTab1 : public CPropertyPage BOOL m_parseall; BOOL m_testall; BOOL m_htmlfirst; + BOOL m_keepwww; + BOOL m_keepslashes; + BOOL m_keepqueryorder; //}}AFX_DATA diff --git a/WinHTTrack/Shell.cpp b/WinHTTrack/Shell.cpp index aebafc3..a396551 100755 --- a/WinHTTrack/Shell.cpp +++ b/WinHTTrack/Shell.cpp @@ -617,6 +617,9 @@ void compute_options() { if(maintab->m_option2.m_hidepwd) ShellOptions->hidepwd = "%x"; else ShellOptions->hidepwd = ""; if(maintab->m_option2.m_hidequery) ShellOptions->hidequery = "%q0"; else ShellOptions->hidequery = ""; + ShellOptions->keepwww = maintab->m_option1.m_keepwww ? "--keep-www-prefix" : ""; + ShellOptions->keepslashes = maintab->m_option1.m_keepslashes ? "--keep-double-slashes" : ""; + ShellOptions->keepqueryorder = maintab->m_option1.m_keepqueryorder ? "--keep-query-order" : ""; ShellOptions->robots = ""; if(maintab->m_option8.m_robots==0) ShellOptions->robots = "s0"; else if(maintab->m_option8.m_robots==1) ShellOptions->robots = "s1"; @@ -2015,6 +2018,11 @@ void lance(void) { args.Add("--pause"); args.Add(ShellOptions->pausefiles); } + + // URL-hack opt-outs (only meaningful with -%u url hacks on) + if (ShellOptions->keepwww.GetLength() != 0) args.Add(ShellOptions->keepwww); + if (ShellOptions->keepslashes.GetLength() != 0) args.Add(ShellOptions->keepslashes); + if (ShellOptions->keepqueryorder.GetLength() != 0) args.Add(ShellOptions->keepqueryorder); // mode spider, mettre après options if (ShellOptions->choixdeb[0]=='!') { @@ -2500,6 +2508,9 @@ void Write_profile(CString path,int load_path) { MyWriteProfileInt(path,strSection, "Test",maintab->m_option1.m_testall); MyWriteProfileInt(path,strSection, "ParseAll",maintab->m_option1.m_parseall); MyWriteProfileInt(path,strSection, "HTMLFirst",maintab->m_option1.m_htmlfirst); + MyWriteProfileInt(path,strSection, "KeepWww",maintab->m_option1.m_keepwww); + MyWriteProfileInt(path,strSection, "KeepSlashes",maintab->m_option1.m_keepslashes); + MyWriteProfileInt(path,strSection, "KeepQueryOrder",maintab->m_option1.m_keepqueryorder); MyWriteProfileInt(path,strSection, "Cache",maintab->m_option3.m_cache); MyWriteProfileInt(path,strSection, "NoRecatch",maintab->m_option9.m_norecatch); MyWriteProfileInt(path,strSection, "Dos", @@ -2598,6 +2609,12 @@ void Write_profile(CString path,int load_path) { MyWriteProfileInt(path,strSection,"ParseAll", n); n=maintab->m_option1.IsDlgButtonChecked(IDC_htmlfirst); MyWriteProfileInt(path,strSection,"HTMLFirst", n); + n=maintab->m_option1.IsDlgButtonChecked(IDC_keepwww); + MyWriteProfileInt(path,strSection,"KeepWww", n); + n=maintab->m_option1.IsDlgButtonChecked(IDC_keepslashes); + MyWriteProfileInt(path,strSection,"KeepSlashes", n); + n=maintab->m_option1.IsDlgButtonChecked(IDC_keepqueryorder); + MyWriteProfileInt(path,strSection,"KeepQueryOrder", n); // 2 n=maintab->m_option3.IsDlgButtonChecked(IDC_Cache); MyWriteProfileInt(path,strSection,"Cache", n); @@ -2831,6 +2848,9 @@ void Read_profile(CString path,int load_path) { maintab->m_option1.m_testall = MyGetProfileInt(path,strSection, "Test",0); maintab->m_option1.m_parseall = MyGetProfileInt(path,strSection, "ParseAll",1); maintab->m_option1.m_htmlfirst = MyGetProfileInt(path,strSection, "HTMLFirst",0); + maintab->m_option1.m_keepwww = MyGetProfileInt(path,strSection, "KeepWww",0); + maintab->m_option1.m_keepslashes = MyGetProfileInt(path,strSection, "KeepSlashes",0); + maintab->m_option1.m_keepqueryorder = MyGetProfileInt(path,strSection, "KeepQueryOrder",0); maintab->m_option3.m_cache = MyGetProfileInt(path,strSection, "Cache",1); maintab->m_option9.m_norecatch = MyGetProfileInt(path,strSection, "NoRecatch",0); maintab->m_option2.m_dos = (MyGetProfileInt(path,strSection, "Dos",0) & 1); diff --git a/WinHTTrack/Shell.h b/WinHTTrack/Shell.h index 4852232..3fe303f 100755 --- a/WinHTTrack/Shell.h +++ b/WinHTTrack/Shell.h @@ -205,7 +205,7 @@ class CShellOptions { toler, updhack, urlhack, http10, waittime, maxtime, maxrate, maxconn, maxlinks, hh, mm, ss, buff_filtres, buff_MIME, _RasString, accept_language, other_headers, default_referer, - cookiesfile, pausefiles; + cookiesfile, pausefiles, keepwww, keepslashes, keepqueryorder; CString LINE_back; RASDIALPARAMS _dial; }; diff --git a/WinHTTrack/WinHTTrack.rc b/WinHTTrack/WinHTTrack.rc index ffe9b70..ba2c385 100755 --- a/WinHTTrack/WinHTTrack.rc +++ b/WinHTTrack/WinHTTrack.rc @@ -573,7 +573,7 @@ BEGIN EDITTEXT IDC_accept_language,115,54,180,12,ES_AUTOHSCROLL END -IDD_OPTION1 DIALOG 0, 0, 325, 105 +IDD_OPTION1 DIALOG 0, 0, 325, 150 STYLE DS_SETFONT | WS_CHILD | WS_DISABLED | WS_CAPTION | WS_SYSMENU CAPTION "Links" FONT 8, "MS Sans Serif" @@ -585,6 +585,9 @@ BEGIN CONTROL "Test validity of all links (even external ones)",IDC_testall, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,64,309,10 CONTROL "Get HTML files first!",IDC_htmlfirst,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,85,309,10 + CONTROL "Keep the www. prefix (do not merge www.host with host)",IDC_keepwww,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,101,309,10 + CONTROL "Keep double slashes in URLs",IDC_keepslashes,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,117,309,10 + CONTROL "Keep the original query-string order",IDC_keepqueryorder,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,133,309,10 END IDD_OPTION2 DIALOG 0, 0, 296, 150 diff --git a/WinHTTrack/cpp_lang.h b/WinHTTrack/cpp_lang.h index 1e964ce..756487f 100644 --- a/WinHTTrack/cpp_lang.h +++ b/WinHTTrack/cpp_lang.h @@ -474,6 +474,12 @@ #define LANG_COOKIEFILETIP LANGSEL("LANG_COOKIEFILETIP") #define LANG_PAUSEFILES LANGSEL("LANG_PAUSEFILES") #define LANG_PAUSEFILESTIP LANGSEL("LANG_PAUSEFILESTIP") +#define LANG_KEEPWWW LANGSEL("LANG_KEEPWWW") +#define LANG_KEEPWWWTIP LANGSEL("LANG_KEEPWWWTIP") +#define LANG_KEEPSLASHES LANGSEL("LANG_KEEPSLASHES") +#define LANG_KEEPSLASHESTIP LANGSEL("LANG_KEEPSLASHESTIP") +#define LANG_KEEPQUERYORDER LANGSEL("LANG_KEEPQUERYORDER") +#define LANG_KEEPQUERYORDERTIP LANGSEL("LANG_KEEPQUERYORDERTIP") #endif diff --git a/WinHTTrack/resource.h b/WinHTTrack/resource.h index eb615ef..e575eaa 100644 --- a/WinHTTrack/resource.h +++ b/WinHTTrack/resource.h @@ -512,6 +512,9 @@ #define IDC_STATIC_cookiesfile 1312 #define IDC_pausefiles 1313 #define IDC_STATIC_pausefiles 1314 +#define IDC_keepwww 1315 +#define IDC_keepslashes 1316 +#define IDC_keepqueryorder 1317 #define ID_MENUITEM32771 32771 #define ID_MENUITEM32772 32772 #define ID_EXIT 32772 @@ -583,7 +586,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 247 #define _APS_NEXT_COMMAND_VALUE 32837 -#define _APS_NEXT_CONTROL_VALUE 1315 +#define _APS_NEXT_CONTROL_VALUE 1318 #define _APS_NEXT_SYMED_VALUE 108 #endif #endif From ee3af32ca292201f999150e25aff69da70ee3265 Mon Sep 17 00:00:00 2001 From: Xavier Roche Date: Wed, 15 Jul 2026 15:49:38 +0200 Subject: [PATCH 6/7] Expose --strip-query on the Experts tab The engine (3.49-10) can drop selected query-string keys from the dedup naming. Add a "Strip query keys" field to the Experts tab, persist it as StripQuery, and emit --strip-query when set. LANG keys LANG_STRIPQUERY / LANG_STRIPQUERYTIP wired; translations follow engine-side. Co-Authored-By: Claude Opus 4.8 (1M context) --- WinHTTrack/OptionTab3.cpp | 8 ++++++++ WinHTTrack/OptionTab3.h | 1 + WinHTTrack/Shell.cpp | 11 +++++++++++ WinHTTrack/Shell.h | 3 ++- WinHTTrack/WinHTTrack.rc | 2 ++ WinHTTrack/cpp_lang.h | 2 ++ WinHTTrack/resource.h | 4 +++- 7 files changed, 29 insertions(+), 2 deletions(-) diff --git a/WinHTTrack/OptionTab3.cpp b/WinHTTrack/OptionTab3.cpp index ebf280b..e83d346 100755 --- a/WinHTTrack/OptionTab3.cpp +++ b/WinHTTrack/OptionTab3.cpp @@ -32,6 +32,7 @@ COptionTab3::COptionTab3() : CPropertyPage(COptionTab3::IDD) m_windebug = FALSE; m_cache = FALSE; m_travel3 = -1; + m_stripquery = _T(""); //}}AFX_DATA_INIT } @@ -53,6 +54,7 @@ void COptionTab3::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_windebug, m_windebug); DDX_Check(pDX, IDC_Cache, m_cache); DDX_CBIndex(pDX, IDC_travel3, m_travel3); + DDX_Text(pDX, IDC_stripquery, m_stripquery); //}}AFX_DATA_MAP } @@ -82,6 +84,8 @@ BOOL COptionTab3::OnInitDialog() GetDlgItem(IDC_STATIC_primf) ->ModifyStyle(0,WS_DISABLED); GetDlgItem(IDC_STATIC_travel) ->ModifyStyle(0,WS_DISABLED); GetDlgItem(IDC_STATIC_travel2) ->ModifyStyle(0,WS_DISABLED); + GetDlgItem(IDC_stripquery) ->ModifyStyle(0,WS_DISABLED); + GetDlgItem(IDC_STATIC_stripquery)->ModifyStyle(0,WS_DISABLED); } else { GetDlgItem(IDC_Cache) ->ModifyStyle(WS_DISABLED,0); GetDlgItem(IDC_filter) ->ModifyStyle(WS_DISABLED,0); @@ -92,6 +96,8 @@ BOOL COptionTab3::OnInitDialog() GetDlgItem(IDC_STATIC_travel) ->ModifyStyle(WS_DISABLED,0); GetDlgItem(IDC_STATIC_travel2) ->ModifyStyle(WS_DISABLED,0); GetDlgItem(IDC_STATIC_travel3) ->ModifyStyle(WS_DISABLED,0); + GetDlgItem(IDC_stripquery) ->ModifyStyle(WS_DISABLED,0); + GetDlgItem(IDC_STATIC_stripquery)->ModifyStyle(WS_DISABLED,0); } // Patcher l'interface pour les Français ;-) @@ -102,6 +108,7 @@ BOOL COptionTab3::OnInitDialog() SetDlgItemTextCP(this, IDC_STATIC_travel2,LANG(LANG_I40b)); // "Mode de parcours"); SetDlgItemTextCP(this, IDC_STATIC_warning,LANG(LANG_I40c)); SetDlgItemTextCP(this, IDC_STATIC_travel3,LANG(LANG_I40e)); + SetDlgItemTextCP(this, IDC_STATIC_stripquery,LANG(LANG_STRIPQUERY)); SetDlgItemTextCP(this, IDC_windebug,LANG_I40d); // Activate debug mode (winhttrack.log) SetCombo(this,IDC_filter,LISTDEF_4); SetCombo(this,IDC_travel,LISTDEF_5); @@ -158,6 +165,7 @@ const char* COptionTab3::GetTip(int ID) case IDC_travel2: return LANG(LANG_I11b); break; // "Select the travel direction in the site","Sélection de la direction du miroir"); break; case IDC_travel3: return LANG(LANG_I11c); break; case IDC_windebug: return LANG_I1h; break; + case IDC_stripquery: return LANG(LANG_STRIPQUERYTIP); break; } return ""; } diff --git a/WinHTTrack/OptionTab3.h b/WinHTTrack/OptionTab3.h index a4bf378..2159d31 100644 --- a/WinHTTrack/OptionTab3.h +++ b/WinHTTrack/OptionTab3.h @@ -35,6 +35,7 @@ class COptionTab3 : public CPropertyPage BOOL m_windebug; BOOL m_cache; int m_travel3; + CString m_stripquery; //}}AFX_DATA diff --git a/WinHTTrack/Shell.cpp b/WinHTTrack/Shell.cpp index a396551..02f0525 100755 --- a/WinHTTrack/Shell.cpp +++ b/WinHTTrack/Shell.cpp @@ -688,6 +688,7 @@ void compute_options() { else if (maintab->m_option3.m_travel3==1) ShellOptions->filtre += "K"; else if (maintab->m_option3.m_travel3==2) ShellOptions->filtre += "K3"; else if (maintab->m_option3.m_travel3==3) ShellOptions->filtre += "K4"; + ShellOptions->stripquery = maintab->m_option3.m_stripquery; if (maintab->m_option9.m_logf) ShellOptions->log = "f2"; else ShellOptions->log = "Q"; @@ -2023,6 +2024,12 @@ void lance(void) { if (ShellOptions->keepwww.GetLength() != 0) args.Add(ShellOptions->keepwww); if (ShellOptions->keepslashes.GetLength() != 0) args.Add(ShellOptions->keepslashes); if (ShellOptions->keepqueryorder.GetLength() != 0) args.Add(ShellOptions->keepqueryorder); + + // drop selected query keys from the dedup naming (--strip-query) + if (ShellOptions->stripquery.GetLength() != 0) { + args.Add("--strip-query"); + args.Add(ShellOptions->stripquery); + } // mode spider, mettre après options if (ShellOptions->choixdeb[0]=='!') { @@ -2550,6 +2557,7 @@ void Write_profile(CString path,int load_path) { MyWriteProfileInt(path,strSection, "Travel",maintab->m_option3.m_travel); MyWriteProfileInt(path,strSection, "GlobalTravel",maintab->m_option3.m_travel2); MyWriteProfileInt(path,strSection, "RewriteLinks",maintab->m_option3.m_travel3); + MyWriteProfileString(path,strSection, "StripQuery",maintab->m_option3.m_stripquery); MyWriteProfileString(path,strSection, "BuildString",maintab->m_option2.Bopt.m_BuildString); // champs @@ -2656,6 +2664,8 @@ void Write_profile(CString path,int load_path) { MyWriteProfileInt(path,strSection, "GlobalTravel", n); if ((n=maintab->m_option3.m_ctl_travel3.GetCurSel()) != CB_ERR) MyWriteProfileInt(path,strSection, "RewriteLinks", n); + maintab->m_option3.GetDlgItemText(IDC_stripquery,st); + MyWriteProfileString(path,strSection, "StripQuery", st); // maintab->m_option8.GetDlgItemText(IDC_robots,st); MyWriteProfileString(path,strSection, "FollowRobotsTxt", st); @@ -2886,6 +2896,7 @@ void Read_profile(CString path,int load_path) { maintab->m_option3.m_travel = MyGetProfileInt(path,strSection, "Travel",1); maintab->m_option3.m_travel2 = MyGetProfileInt(path,strSection, "GlobalTravel",0); maintab->m_option3.m_travel3 = MyGetProfileInt(path,strSection, "RewriteLinks",0); + maintab->m_option3.m_stripquery = MyGetProfileString(path,strSection, "StripQuery"); maintab->m_option2.Bopt.m_BuildString = MyGetProfileString(path,strSection, "BuildString","%h%p/%n%q.%t"); // champs diff --git a/WinHTTrack/Shell.h b/WinHTTrack/Shell.h index 3fe303f..631cf49 100755 --- a/WinHTTrack/Shell.h +++ b/WinHTTrack/Shell.h @@ -205,7 +205,8 @@ class CShellOptions { toler, updhack, urlhack, http10, waittime, maxtime, maxrate, maxconn, maxlinks, hh, mm, ss, buff_filtres, buff_MIME, _RasString, accept_language, other_headers, default_referer, - cookiesfile, pausefiles, keepwww, keepslashes, keepqueryorder; + cookiesfile, pausefiles, keepwww, keepslashes, keepqueryorder, + stripquery; CString LINE_back; RASDIALPARAMS _dial; }; diff --git a/WinHTTrack/WinHTTrack.rc b/WinHTTrack/WinHTTrack.rc index ba2c385..0cc8f2e 100755 --- a/WinHTTrack/WinHTTrack.rc +++ b/WinHTTrack/WinHTTrack.rc @@ -496,6 +496,8 @@ BEGIN COMBOBOX IDC_travel2,165,75,130,56,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP LTEXT "Rewrite links: internal / external",IDC_STATIC_travel3,16,92,129,8 COMBOBOX IDC_travel3,16,100,139,56,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + LTEXT "Strip query keys:",IDC_STATIC_stripquery,165,92,150,8 + EDITTEXT IDC_stripquery,165,102,150,12,ES_AUTOHSCROLL CONTROL "Activate Debugging Mode (winhttrack.log)",IDC_windebug, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,120,242,10 END diff --git a/WinHTTrack/cpp_lang.h b/WinHTTrack/cpp_lang.h index 756487f..a1366e5 100644 --- a/WinHTTrack/cpp_lang.h +++ b/WinHTTrack/cpp_lang.h @@ -480,6 +480,8 @@ #define LANG_KEEPSLASHESTIP LANGSEL("LANG_KEEPSLASHESTIP") #define LANG_KEEPQUERYORDER LANGSEL("LANG_KEEPQUERYORDER") #define LANG_KEEPQUERYORDERTIP LANGSEL("LANG_KEEPQUERYORDERTIP") +#define LANG_STRIPQUERY LANGSEL("LANG_STRIPQUERY") +#define LANG_STRIPQUERYTIP LANGSEL("LANG_STRIPQUERYTIP") #endif diff --git a/WinHTTrack/resource.h b/WinHTTrack/resource.h index e575eaa..bcb6ca9 100644 --- a/WinHTTrack/resource.h +++ b/WinHTTrack/resource.h @@ -515,6 +515,8 @@ #define IDC_keepwww 1315 #define IDC_keepslashes 1316 #define IDC_keepqueryorder 1317 +#define IDC_stripquery 1318 +#define IDC_STATIC_stripquery 1319 #define ID_MENUITEM32771 32771 #define ID_MENUITEM32772 32772 #define ID_EXIT 32772 @@ -586,7 +588,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 247 #define _APS_NEXT_COMMAND_VALUE 32837 -#define _APS_NEXT_CONTROL_VALUE 1318 +#define _APS_NEXT_CONTROL_VALUE 1320 #define _APS_NEXT_SYMED_VALUE 108 #endif #endif From 58419041ce3866c610dc769af7b39e4b6f5a2934 Mon Sep 17 00:00:00 2001 From: Xavier Roche Date: Wed, 15 Jul 2026 18:25:23 +0200 Subject: [PATCH 7/7] GUI review polish: cookies-file browse button, clearer pause/strip labels Follow-up to the option-exposure work, from GUI review: - Add a "..." Browse button next to the cookies-file field that opens a file picker (CFileDialog), reusing the existing filter idiom. - Label the pause field "Pause between files (s):" to disambiguate it from the pre-existing byte-based "Pause after downloading .. B" on Limits. - Give the strip-query field an inline example, "Strip query keys (e.g. sid,ref):", since its tooltip is not yet available. Co-Authored-By: Claude Opus 4.8 (1M context) --- WinHTTrack/OptionTab8.cpp | 11 +++++++++++ WinHTTrack/OptionTab8.h | 1 + WinHTTrack/WinHTTrack.rc | 7 ++++--- WinHTTrack/resource.h | 3 ++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/WinHTTrack/OptionTab8.cpp b/WinHTTrack/OptionTab8.cpp index 2b3431c..c698bd8 100755 --- a/WinHTTrack/OptionTab8.cpp +++ b/WinHTTrack/OptionTab8.cpp @@ -61,12 +61,23 @@ void COptionTab8::DoDataExchange(CDataExchange* pDX) BEGIN_MESSAGE_MAP(COptionTab8, CPropertyPage) //{{AFX_MSG_MAP(COptionTab8) + ON_BN_CLICKED(IDC_cookiesfilebrowse, OnCookiesFileBrowse) //}}AFX_MSG_MAP ON_NOTIFY_EX( TTN_NEEDTEXT, 0, OnToolTipNotify ) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // COptionTab8 message handlers + +void COptionTab8::OnCookiesFileBrowse() +{ + // writable buffer: CFileDialog rewrites the '|' separators in place + char szFilter[] = "Cookies file (cookies.txt, *.txt)|*.txt|All files (*.*)|*.*||"; + CFileDialog dial(TRUE, "txt", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, szFilter); + if (dial.DoModal() == IDOK) + SetDlgItemTextCP(this, IDC_cookiesfile, dial.GetPathName()); +} + BOOL COptionTab8::OnInitDialog() { CDialog::OnInitDialog(); diff --git a/WinHTTrack/OptionTab8.h b/WinHTTrack/OptionTab8.h index 34246e8..07d647e 100644 --- a/WinHTTrack/OptionTab8.h +++ b/WinHTTrack/OptionTab8.h @@ -48,6 +48,7 @@ class COptionTab8 : public CPropertyPage // Generated message map functions //{{AFX_MSG(COptionTab8) virtual BOOL OnInitDialog(); + afx_msg void OnCookiesFileBrowse(); //}}AFX_MSG afx_msg BOOL OnToolTipNotify( UINT id, NMHDR * pNMHDR, LRESULT * pResult ); DECLARE_MESSAGE_MAP() diff --git a/WinHTTrack/WinHTTrack.rc b/WinHTTrack/WinHTTrack.rc index 0cc8f2e..27a9f84 100755 --- a/WinHTTrack/WinHTTrack.rc +++ b/WinHTTrack/WinHTTrack.rc @@ -496,7 +496,7 @@ BEGIN COMBOBOX IDC_travel2,165,75,130,56,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP LTEXT "Rewrite links: internal / external",IDC_STATIC_travel3,16,92,129,8 COMBOBOX IDC_travel3,16,100,139,56,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP - LTEXT "Strip query keys:",IDC_STATIC_stripquery,165,92,150,8 + LTEXT "Strip query keys (e.g. sid,ref):",IDC_STATIC_stripquery,165,92,150,8 EDITTEXT IDC_stripquery,165,102,150,12,ES_AUTOHSCROLL CONTROL "Activate Debugging Mode (winhttrack.log)",IDC_windebug, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,120,242,10 @@ -520,7 +520,7 @@ BEGIN EDITTEXT IDC_rate,130,95,32,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "B/s",IDC_STATIC,170,95,17,8 CONTROL "Remove host if low",IDC_rems,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,130,109,183,10 - LTEXT "Pause between files:",IDC_STATIC_pausefiles,16,124,110,8 + LTEXT "Pause between files (s):",IDC_STATIC_pausefiles,16,124,110,8 EDITTEXT IDC_pausefiles,130,122,45,12,ES_AUTOHSCROLL END @@ -640,7 +640,8 @@ BEGIN CONTROL "Tolerant requests (for servers)",IDC_toler,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,110,244,9 CONTROL "Force old HTTP/1.0 requests (no 1.1)",IDC_http10,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,125,237,9 LTEXT "Load cookies from file:",IDC_STATIC_cookiesfile,16,144,120,8 - EDITTEXT IDC_cookiesfile,140,142,116,12,ES_AUTOHSCROLL + EDITTEXT IDC_cookiesfile,140,142,96,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_cookiesfilebrowse,240,142,16,12 END IDD_OPTION9 DIALOGEX 0, 0, 325, 143 diff --git a/WinHTTrack/resource.h b/WinHTTrack/resource.h index bcb6ca9..9131af2 100644 --- a/WinHTTrack/resource.h +++ b/WinHTTrack/resource.h @@ -517,6 +517,7 @@ #define IDC_keepqueryorder 1317 #define IDC_stripquery 1318 #define IDC_STATIC_stripquery 1319 +#define IDC_cookiesfilebrowse 1320 #define ID_MENUITEM32771 32771 #define ID_MENUITEM32772 32772 #define ID_EXIT 32772 @@ -588,7 +589,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 247 #define _APS_NEXT_COMMAND_VALUE 32837 -#define _APS_NEXT_CONTROL_VALUE 1320 +#define _APS_NEXT_CONTROL_VALUE 1321 #define _APS_NEXT_SYMED_VALUE 108 #endif #endif