Question

I have a batch file that will launch a .js file which, via WinSCP, checks if a file exists and returns to the batch file if it does or not.

The problem IS: It always returns not found, and I cannot figure out why. I am unsure how to use a wildcard in this scenario.

The batch file looks like this:

cscript /nologo file.js
if errorlevel 1 goto notfound
exit
:notfound
(another script to copy a file over)

Only one file can exist on the server at once. So every ten min, this batch file will run, check if there is a file, if not, copy one over.

The file.js:

// Configuration

// Remote file search for
var FILEPATH = "../filepath/TSS*";

// Session to connect to
var SESSION = "mysession@someplace.come";

// Path to winscp.com
var WINSCP = "c:\\program files (x86)\\winscp\\winscp.com";

var filesys = WScript.CreateObject("Scripting.FileSystemObject");
var shell = WScript.CreateObject("WScript.Shell");

var logfilepath = filesys.GetSpecialFolder(2) + "\\" + filesys.GetTempName() + ".xml";

var p = FILEPATH.lastIndexOf('/');
var path = FILEPATH.substring(0, p);
var filename = FILEPATH.substring(p + 1);

var exec;

// run winscp to check for file existence
exec = shell.Exec("\"" + WINSCP + "\" /log=\"" + logfilepath + "\"");
exec.StdIn.Write(
"option batch abort\n" +
"open \"" + SESSION + "\"\n" +
"ls \"" + path + "\"\n" +
"exit\n");

// wait until the script finishes
while (exec.Status == 0)
{
WScript.Sleep(100);
WScript.Echo(exec.StdOut.ReadAll());
}

if (exec.ExitCode != 0)
{
WScript.Echo("Error checking for file existence");
WScript.Quit(1);
}

// look for log file
var logfile = filesys.GetFile(logfilepath);

if (logfile == null)
{
WScript.Echo("Cannot find log file");
WScript.Quit(1);
}

// parse XML log file
var doc = new ActiveXObject("MSXML2.DOMDocument");
doc.async = false;
doc.load(logfilepath);

doc.setProperty("SelectionNamespaces", 
"xmlns:w='http://winscp.net/schema/session/1.0'");

var nodes = doc.selectNodes("//w:file/w:filename[@value='" + filename + "']");

if (nodes.length > 0)
{
WScript.Echo("File found");
// signalize file existence to calling process;
// you can also continue with processing (e.g. downloading the file)
// directly from the script here
WScript.Quit(0);
}
else
{
WScript.Echo("File not found");
WScript.Quit(1);
}

On line 4 it says:

var FILEPATH = "../filepath/TSS*";

That star is what is giving me issues, i think. I need to look for a file which STARTS WITH TSS, but will have a time stamp tacked on the end. So i need to just use a wildcard after TSS.

So what i need help with is: Making this process return true if any file exists with TSS*

Any help would be much appreciated.

EDIT:

var nodes = doc.selectNodes("//w:file/w:filename[starts-with(@value, 'TSS')]");

This code seems to not work. If this code worked, it seems like it would solve all my problems.

Was it helpful?

Solution

You need to correct xpath expression in var nodes... line. Try something like this:

doc.setProperty("SelectionLanguage", "XPath"); //added in edit
var nodes = doc.selectNodes("//w:file/w:filename[starts-with(@value, '" + filename + "')]");

and delete asterisk from FILEPATH.

Note: first line is required in order to use XPath as the query language, not default (and old) XSLPattern which doesn't support methods such as starts-with or contains.

SelectionLanguage Property (MDSN).

OTHER TIPS

You can use the stat command. You can even inline the WinSCP script into the batch file:

@echo off

set REMOTE_PATH=/home/user/test.txt
winscp.com /command ^
    "option batch abort" ^
    "open mysession" ^ 
    "stat %REMOTE_PATH%" ^ 
    "exit"

if errorlevel 1 goto error

echo File %REMOTE_PATH% exists
rem Do something
exit 0

:error
echo Error or file %REMOTE_PATH% not exists
exit 1

An alternative is using the Session.FileExists from WinSCP .NET assembly.


For further details, see the WinSCP article Checking file existence.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top