Passing file paths: FORCE quotes?

Looking at why I keep running into trouble passing selected files to PotPlayer, I found out that, somehow, it seems to require quotes around the filenames passed to it.
File paths with spaces in them, the use of "C:\Program Files\DAUM\PotPlayer\PotPlayerMini64.exe" {allfilepath} /sort works fine, since DOpus surrounds those paths with quotes by default, unless specified otherwise (@nofilenamequoting).

Ideas I've had:

  • What happens if I strip all quotes with @nofilenamequoting, surround the files arg with quotes manually and use " "as a separator (|sep) with "C:\Program Files\DAUM\PotPlayer\PotPlayerMini64.exe" "{allfilepath|sep=" "}" @nofilenamequoting or something?
    -> Won't work, I've tried escaping the quotes in various ways, but it looks like sep= really only accepts the first char, not a string
  • Maybe the problem arises from mixed cases and commands without ANY quotes in them would work? (this wouldn't solve the problem but seemed like an interesting question)
    -> No, even CD "C:\Program Files\DAUM\PotPlayer"
    PotPlayerMini64.exe G:\path\withoutspaces.mp4 won't work.

Is there any way for FORCE DOpus to surround all arguments with quotes?
I can hack together a script function, but that seems ugly.

PS: Yes, the particular issue here seems to be a shortcoming of PotPlayer, but after a year or so of trying, their forum still won't verify any of the email accounts I've supplied, so I wasn't able to file a report/request yet :joy:

In the meantime: Here's a command script that creates a command which launches commands surrounding all arguments with quotes:

function OnInit(initData) {
	initData.name = "Call With Quotes";
	initData.desc = initData.name;
	initData.copyright = "(c) 2020 Benjamin Philipp";
	initData.default_enable = true;
	initData.version = "0.1.0";

	// Create a new ScriptCommand object and initialize it to add the command to Opus
	var cmd = initData.AddCommand();
	cmd.name = "CWQ";
	cmd.method = "OnCmd";
	cmd.desc = initData.desc;
	cmd.label = "CWQ";
	cmd.template = "CMD/M";
}

function OnCmd(data){
	DOpus.ClearOutput();
	var args = colToArray(data.func.args.CMD);
	//log(args);
	var cstr = "\"" + args.join("\" \"") + "\"";
	// msg("Result:\n" + cstr);
	data.func.command.RunCommand(cstr);
}


function colToArray(coll){
	var enumFields = new Enumerator(coll); // jshint ignore:line
	enumFields.moveFirst();
	var array = [];
	while (enumFields.atEnd() === false) {
		var i = enumFields.item();
		array.push(i);
		//		log("added: " + i.name);
		enumFields.moveNext();
	}
	return array;
}

function log(obj) {
	DOpus.Output(stringify(obj));
}

function msg(s) {
	var dlg = DOpus.Dlg;
	s = stringify(s);
	log("MSG: " + s);
	dlg.message = s;
	dlg.buttons = "OK";
	dlg.icon = "info";
	var i = dlg.Show();
}

function stringify(obj) {
	if(typeof obj == "undefined")
		obj = "<undefined>";
	else if(obj === null)
		obj = "<null>";
	else if(typeof obj == "object"){
		var o = obj;
		obj = "[Object]\n";
		obj += dump(o);
	} else if(obj === false)
		obj = "FALSE";
	else if(obj === true)
		obj = "TRUE";
	else if(obj==="")
		obj = "<empty>";
	return obj;
}

function dump(arr, level) {
	var dumped_text = "";
	if (!level) level = 0;

	var bs = "\n";

	var level_padding = "	";
	for (var j = 0; j < level + 1; j++) level_padding += "	 ";

	if (typeof (arr) == 'object') { //Array/Hashes/Objects 
		for (var item in arr) {
			var value = arr[item];

			if (typeof (value) == 'object') { //If it is an array,
				dumped_text += level_padding + "'" + item + "'(" + typeof (value) + "){" + bs;
				dumped_text += dump(value, level + 1) + bs + "}";
			} else {
				if(typeof(value.toString)=="function")
					value = value.toString();
				value = "" + value;
				var m = value.match(/function ?\((.*)\) ?\{/i);
				if(m)
					value = "function(" + m[1] + ")";
				dumped_text += level_padding + "'" + item + "' => \"" + value + "\"" + bs;
			}
		}
	} else { //Stings/Chars/Numbers etc.
		dumped_text = "===>" + arr + "<===(" + typeof (arr) + ")";
	}
	return dumped_text;
}

Usage:
prepend your command with CWQ , for example:
Old: "C:\Program Files\DAUM\PotPlayer\PotPlayerMini64.exe" {allfilepath} /sort
->
New: CWQ "C:\Program Files\DAUM\PotPlayer\PotPlayerMini64.exe" {allfilepath} /sort

There's no way to force quotes around {allfilepath}, only for the codes that emit a single path/name at a time.

With sep=x, the x can only be one character as well. (That was added for a program that needed * between paths.)

It's unusual for a program to require quotes around paths that don't contain spaces. This seems like a PotPlayer issue to me, more than anything. I'd be surprised if many other programs needed the same thing.

Using scripting is a good workaround for that kind of thing. I would use a simpler script in the button itself (no script add-in):

function OnClick(clickData)
{
	var cmdLine = '"C:\\Program Files\\DAUM\\PotPlayer\\PotPlayerMini64.exe"'

	var selected = clickData.func.sourcetab.selected;
//	if (selected.count == 0) return; -- to block launching the program with no paths

	for (var eSel = new Enumerator(selected); !eSel.atEnd(); eSel.moveNext())
	{
	//	if (eSel.item().is_dir) continue; -- if you want to skip dirs
		cmdLine += ' "';
		cmdLine += eSel.item().RealPath;
		cmdLine += '"';
	}

	var cmd = clickData.func.command;
	cmd.ClearFiles();
	cmd.RunCommand(cmdLine);
//	DOpus.Output(cmdLine); -- for testing
}
1 Like

Yes, I agree :slight_smile:

Even though I might not ever run into this problem again with anything else, I liked the idea of universality and having an add-in ready for this that I could simply prepend to any regular button command.
But of course your neat button script is the more elegant solution to strictly solve the issue once.

Thanks for the feedback, prompt and helpful as ever! :grinning:

1 Like