using Windows command line, e.g. to find files on disk

Average rating
(1 vote)

Igor can send commands to the Windows command line via ExecuteScriptText, but the manual says it cannot read results back. Here's a little snippet to do just that. You can use this to find directories in the Windows path variable, or to find files (with wild cards) on a disk drive:

print ExecuteWinCmd("echo hello, world!")
  hello, world!print SearchWindowsPath("miktex")
  C:\Programme\MiKTeX 2.7\miktex\bin;
•print FindFilesOnDisk("c", "latex.exe")
  looking for latex.exe on drive c: - please stand by, this may take a long time!
  C:\Programme\MiKTeX 2.7\miktex\bin\latex.exe;

Here's the code you need to paste in your Procedure window:
function/S ExecuteWinCmd(command)
string command
	string IPUFpath = SpecialDirPath("Igor Pro User Files",0,1,0)	// guaranteed writeable path in IP6
	string batchFileName = "ExecuteWinCmd.bat", outputFileName = "ExecuteWinCmd.out"
	string outputLine, result = ""
	variable refNum
 
	NewPath/O/Q IgorProUserFiles, IPUFpath
	Open/P=IgorProUserFiles refNum as batchFileName	// overwrites previous batchfile
	fprintf refNum,"cmd/c \"%s > \"%s%s\"\"\r", command, IPUFpath, outputFileName
	Close refNum
	ExecuteScriptText/B "\"" + IPUFpath + "\\" + batchFileName + "\""
	Open/P=IgorProUserFiles/R refNum as outputFileName
	do
		FReadLine refNum, outputLine
		if( strlen(outputLine) == 0 )
			break
		endif
		result += outputLine
	while( 1 )
	Close refNum
	return result
end
 
function/S SearchWindowsPath(str)
string str
	return ListMatch(ExecuteWinCmd("path"),"*"+str+"*")
end
 
function/S FindFilesOnDisk(driveName, fileName)
string driveName, fileName
	string fileNotFoundString = "_file not found_"	// change this to "", if you prefer an empty string
 
	// allow user to specify "c" or "C:", or even "" (converted to "C:") as the driveName
	switch( strlen(driveName) )
		case 0:
			driveName = "c"	// fall through
		case 1:
			driveName += ":"
		case 2:
			break
		default:
			Abort "illegal drive specification"
	endswitch
 
	// attrib/s is the fastest way to find a file with a given name (with wild cards) anywhere on a disk
	// but it can still take a long time, especially with large hard disks!
	print "looking for "+fileName+" on drive "+driveName+" - please stand by, this may take a long time!"
 
	// here we go... this command returns only when Windows has finished with it
	string found = ExecuteWinCmd("attrib /s "+driveName+"\\"+fileName)
 
	// convert line break characters to ";" to make the answer an Igor list
	found = ReplaceString("\r", found, ";")
 
	string str, result = ""
	variable n, nmax = ItemsInList(found) - 1
 
	// if we get only one item, then it's possible that the file was not found
		// attrib/s then returns something like "file C:\bla.bla not found" 
		// unfortunately, that message is in the local language of the OS !
	if( nmax == 0 )
		str = found[0, strsearch(found, driveName, 0, 2) - 1]	// if the characters before the file name ...
		if( strsearch(str, UpperStr(str), 0) < 0 )		// ... contain lower case characters ...
			return fileNotFoundString			// ... we assume the file was not found
		endif
	endif
 
	// the file was probably found, maybe even more than once	
		// attrib/s then returns something like "A  HR  C:\jack\data\bla.bla"
		// the length of the attribute list seems unpredictable, but it's all uppercase
	for( n = nmax; n >= 0; n -= 1 )
		str = StringFromList(n, found)					// for each item
		str = str[strsearch(str, driveName, 0, 2), strlen(str)-1]	// excise file path
		result = AddListItem(str, result)				// add to result list
	endfor
	return result
end

I would be happy about feedback from testers, especially of the FindFilesOnDisk routine since it contains some assumptions about international Windows systems (see code documentation).

Back to top