Feature Request: Allow Windows users to define custom directory for configuration (.xml) files

Moderator: Project members

Post Reply
Message
Author
iambesi
500 Command not understood
Posts: 2
Joined: 2021-12-03 01:43
First name: Bernard
Last name: Simmons

Feature Request: Allow Windows users to define custom directory for configuration (.xml) files

#1 Post by iambesi » 2021-12-05 01:55

Hello FileZilla Developers,

In the FileZilla Client, the Windows version defaults to saving the configuration files -- i.e., filezilla.xml, layout.xml, and recentservers.xml -- to the %APPDATA%\FileZilla directory (or the current directory of the filezilla.exe executable if (and only if) for some reason the aforementioned directory fails.) On the Linux version, however, it checks if the $XDG_CONFIG_HOME environment variable is defined, followed by the $HOME/.config and $HOME/filezilla directories respectively. And if found, it looks like it tries to use the $XDG_CONFIG_HOME/filezilla directory as the preferred one.

For that reason, I am wondering why is there not a similar behaviour in the Windows version? In the case of the installed version, it makes perfect sense to use the %APPDATA%\FileZilla directory; however, when using the ‘portable’ (.zip) version, there should at least be some flexibility via a specific environment variable or the like. Case in point, if a user has FileZilla on a USB drive and uses it on PC 1, the configuration and preferences are saved locally; and consequently, when said user moves his or her USB drive to a different PC, the settings are left behind on the previous PC.

With that said, I propose having an environment variable -- e.g., FZ_CONFIG_ROOT -- in Windows that could be checked and used as the directory for saving configuration files. Looking at source code -- specifically in the commonui\fz_paths.cpp file, I think that it would be fairly easily to make this tweak. While I am not a proper developer, I took a stab at updating the existing code (as seen below.)

[ fz_paths.cpp ]

Code: Select all

#ifndef FZ_WINDOWS
namespace {
static std::wstring TryDirectory(std::wstring path, std::wstring const& suffix, bool check_exists)
{
	if (!path.empty() && path[0] == '/') {
		if (path[path.size() - 1] != '/') {
			path += '/';
		}

		path += suffix;

		if (check_exists) {
			if (!CLocalPath(path).Exists(nullptr)) {
				path.clear();
			}
		}
	}
	else {
		path.clear();
	}
	return path;
}
}
// BEGIN ADDED SECTION.
#else
namespace {
static std::wstring TryDirectory(std::wstring path, std::wstring const& suffix, bool check_exists)
{
	if (!path.empty()) {
		if (path[path.size() - 1] == '\\') {
			path = path.substr(0, path.size() - 1);
		
			if (check_exists) {
				if (!CLocalPath(path).Exists(nullptr)) {
					path.clear();
				}
			}
		}
	}
	else {
		path.clear();
	}
	return path;
}
}
// END ADDED SECTION.
#endif

[ … ]

CLocalPath GetUnadjustedSettingsDir()
{
	CLocalPath ret;

#ifdef FZ_WINDOWS
	wchar_t* out{};
	
	// BEGIN ADDED SECTION.
	
	// Check if the user has set the FZ_CONFIG_ROOT environment variable.
	if ( GetEnv("FZ_CONFIG_ROOT") != null )
	{
		std::wstring cfg = TryDirectory(GetEnv("FZ_CONFIG_ROOT"), L"", true);  // check if the path truly exists.
		
		if (!cfg.empty()) {  // if it does, set it and append the '.config' subdirectory to the specified root.
			std:wstring const& dir = cfg;
			ret.SetPath(dir);
			ret.AddSegment(L".config");
		}
	}
	
	if ( ret.empty() )  // If the FZ_CONFIG_ROOT environment variable is not set or the specified path does not exist
	{                   // (or if running the installed version of Filezilla), proceed with the normal %APPDATA% path.
	// END ADDED SECTION.
		if (SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, 0, &out) == S_OK) {
			ret.SetPath(out);
			CoTaskMemFree(out);
		}
		if (!ret.empty()) {
			ret.AddSegment(L"FileZilla");
		}
	}

	if (ret.empty()) {
		// Fall back to directory where the executable is
		std::wstring const& dir = GetOwnExecutableDir();
		ret.SetPath(dir);
	}
#else
	std::wstring cfg = TryDirectory(GetEnv("XDG_CONFIG_HOME"), L"filezilla/", true);
	if (cfg.empty()) {
		cfg = TryDirectory(GetEnv("HOME"), L".config/filezilla/", true);
	}
	if (cfg.empty()) {
		cfg = TryDirectory(GetEnv("HOME"), L".filezilla/", true);
	}
	if (cfg.empty()) {
		cfg = TryDirectory(GetEnv("XDG_CONFIG_HOME"), L"filezilla/", false);
	}
	if (cfg.empty()) {
		cfg = TryDirectory(GetEnv("HOME"), L".config/filezilla/", false);
	}
	if (cfg.empty()) {
		cfg = TryDirectory(GetEnv("HOME"), L".filezilla/", false);
	}
	ret.SetPath(cfg);
#endif
	return ret;
}
[ … ]
In short, I really enjoy using FileZilla for my secure SFTP connections and it is hands down better than WinSCP any day. Thus, I truly hope that this code (or similar) can be implemented in a very near-future version of FileZilla.

Thanks and regards,
iambesi

User avatar
boco
Contributor
Posts: 26913
Joined: 2006-05-01 03:28
Location: Germany

Re: Feature Request: Allow Windows users to define custom directory for configuration (.xml) files

#2 Post by boco » 2021-12-05 02:52

That functionality is set via fzdefaults.xml - a template skeleton of that file is located in the .\docs subdirectory. Instructions are inside.
No support requests over PM! You will NOT get any reply!!!
FTP connection problems? Please read Network Configuration.
FileZilla connection test: https://filezilla-project.org/conntest.php
FileZilla Pro support: https://customerforum.fileZilla-project.org

iambesi
500 Command not understood
Posts: 2
Joined: 2021-12-03 01:43
First name: Bernard
Last name: Simmons

Re: Feature Request: Allow Windows users to define custom directory for configuration (.xml) files

#3 Post by iambesi » 2021-12-09 01:17

Hello boco,

You hit the nail on the head! This is exactly what I was looking to do, and now, I am cooking on gas. 8) I truly thank you for your help!

Best regards,
iambesi

Post Reply