Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations dencom on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

how to run a cmd program from HTA? 3

Status
Not open for further replies.

barny2006

MIS
Mar 30, 2006
521
US
Hi,
i have an hta program that backs up files from c: drive to a cd. i have finished all the components of the hta, inputs, drives, file selections, etc. but the cd copy command is a dos app that runs from the command prompt. this command runs from vbs but when i imbed the vb script in the hta, it doesn't run. the cmd screen flashes and goes away, instead of staying and displaying the dos command and the results of the copy.
here's what i have tried:
Code:
wshshell.Run("cmd.exe /c createcd.exe d: c:\folder\file.txt")
it doesn't work
then i tried this:
Code:
Set wseExternal = wshShell.Exec("wscript.exe //NOLOGO xxx.vbs")
xxx.vbs is the program that runs the same command that didn't work in the above.
if i run xxx.vbs by itself, it works.
any ideas how to get around this?
thanks




 
Is createcd.exe in the same directory as you .hta?

--------------------------------------------------------------------------------
dm4ever
My philosophy: K.I.S.S - Keep It Simple Stupid
 
dm,
you're right. createcd.exe was not in the same directory. i've got that part to work now. i've run into a different problem. here's the problem:
the format of the createcd.exe is:
createcd.exe driveletter file file file file file
e.g.
createcd.exe d: file1 file2 file3 file4 file5 ....
as you can see, the files are separated by a space.
when the file has a space in it, like "my file" then the program looks at it as "my" being one file and "file" being the second file, thus, not being able to find it. i know you can run into the same problem with some dos commands, which doesn't like spaces in file names.
at this point, i'm thinking about taking the file names from windows, and replacing the space with "_" (underscore) and writing it to cd. then i have to come up with a method at restore time, to convert these "_"'s to a space or something.
i certainly thank you all for helping me on this project. i'm sure i'll be able to get it to work.
this program "createcd.exe" is the only one that i have found to be working from an app, such as hta or vbs. i'm open to any suggestions as to what other programs are available.
thanks again.
 
Not sure how you're current code looks like, but here's an example of what may work for you. This is basically making sure " are put around each file name.

Code:
Dim strCmd, strDLetter, arrFiles, strFileName

strDLetter = "d:"
arrFiles = Array("my file", "file1", "some other file", "file5")
strCmd = "createcd.exe " & strDLetter
For Each strFileName In arrFiles
	strCmd = strCmd & " " & Chr(34) & strFileName & Chr(34)
Next

WScript.Echo strCmd

--------------------------------------------------------------------------------
dm4ever
My philosophy: K.I.S.S - Keep It Simple Stupid
 
dm,
thanks a bunch. you've been a lot of help and guidance on this.
i got your advice, and got the space thingy to work ok with chr(34).
now, my problem is with the windows common dialog file select box. vbs works ok with the file names as are being given to it. i.e. "my file.txt" or "some other file.txt".
however, the dialog box where i select the files using windows common dialog file box, changes long files names with spaces in it into something with "~" in it and shortens it to 8 letters. like this:
"my first file.txt" becomes "myfirs~1.txt" or
"some other file.txt" becomres "some o~1.txt"
if i can find a way to fix this "~" problem, my project is done.
thanks again for help.
 
The following code will return the full path of each text file selected (no short names). Just modify it accordingly to your needs.

Code:
Option Explicit
'On Error Resume Next

Dim objDialog, errRtn, arrTemp, strPath, i

Const cdlOFNAllowMultiselect = &H200

Set objDialog = CreateObject("UserAccounts.CommonDialog")
objDialog.Filter = "VBScripts|*.vbs|Text Documents|*.txt|All Files|*.*"
objDialog.FilterIndex = 3
objDialog.InitialDir = "c:\temp"
objDialog.Flags = cdlOFNAllowMultiselect
errRtn = objDialog.ShowOpen()

If errRtn = False Then
	Wscript.Echo "No file selected!"
	Wscript.Quit
Else
	If InStr(objDialog.FileName, "\ ") Then
		arrTemp = Split(objDialog.FileName, " ")
		strPath = arrTemp(0)
		For i = 1 To UBound(arrTemp)
			WScript.Echo GetLongName(strPath & arrTemp(i))
		Next
	Else
		WScript.Echo GetLongName(objDialog.FileName)
	End If
End If 


Function GetLongName(strFileName)
' 	On Error Resume Next
	
	Dim objShell, ObjFSO, objFile, objFolder, objItem
	
	Set objShell = CreateObject("Shell.Application")
	Set ObjFSO = CreateObject("Scripting.FileSystemObject")
	Set objFile = ObjFSO.GetFile(strFileName)
	Set objFolder = objShell.NameSpace(objFile.ParentFolder.Path)
	Set objItem = objFolder.ParseName(objFile.Name)
	GetLongName = objItem.Path
End Function

--------------------------------------------------------------------------------
dm4ever
My philosophy: K.I.S.S - Keep It Simple Stupid
 
Here is a little sample that will let you browse to a file and will return the file name.

Code:
set oFO = CreateObject("SAFRCFileDlg.FileOpen")
' browse to file name thanks to safrcdlg.dll
oFO.OpenFileOpenDlg
' show what the user clicked on.
wscript.echo oFO.FileName

Note that the above code requires safrcdld.dll which is a file from Windows XP. If you are using Vista you would need to copy that file to the machine and register the DLL to make it work. Not ehtat due to Vista security, you cannot install the file in the System32 directory like it would be on XP.

I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
 
mark, dm,
thanks so much.
i will use these codes. however, is there a way to stop the common dialog box from shortening file names with spaces in it into 8dot3?
i modified the registry entry:
HKLM\System\CurrentControlSet\Control\FileSystem
entry to "1" instead of "0" i suppose this prevents ntfs from changing long file names into 8dot3. but still no joy.
the common dialog box still show file names with spaces in it like "my file.txt", as "myfile~1.txt
i will incorporate you alls suggestions to see what happens.
thanks again.
 
The method mark posted will return the full filename without shortening it. However, if I remember correctly you want the ability to select multiple files, which that method does not allow. Using UserAccounts.CommonDialog will also return the full file name, but it does not seem it can do that when allowing for multiple file selection. The example I posted is intended to get around that.

--------------------------------------------------------------------------------
dm4ever
My philosophy: K.I.S.S - Keep It Simple Stupid
 
dm,
you're right. i need multiple file select. and i tried mark's code, it just opens explorer type dialog. which the previous method did without shortening the name. here's the code i had before:
Code:
ObjFSO.Flags = cdlOFNAllowMultiselect
if i just put
Code:
ObjFSO.Flags = cdlOFNExplorer
it will give me the same result as mark mentioned (without multiselect) and it displays file names correctly without shortening them.
i'm looking for multiselect with non-shortened file names.
thanks.

 
You can also try the following which I think might be closer to what you're going for. The output from selecting multiple files will be output like this.

createcd.exe D: "some file.txt" "file1.txt" "some other file.txt"

Code:
Option Explicit
'On Error Resume Next

Dim objDialog, errRtn, arrTemp, strPath, i, strCmd

Const cdlOFNAllowMultiselect = &H200

strCmd = "createcd.exe D:"

Set objDialog = CreateObject("UserAccounts.CommonDialog")
objDialog.Filter = "VBScripts|*.vbs|Text Documents|*.txt|All Files|*.*"
objDialog.FilterIndex = 3
objDialog.InitialDir = "d:\temp"
objDialog.Flags = cdlOFNAllowMultiselect
errRtn = objDialog.ShowOpen()

If errRtn = False Then
	Wscript.Echo "No file selected!"
	Wscript.Quit
Else
	If InStr(objDialog.FileName, "\ ") Then
		arrTemp = Split(objDialog.FileName, " ")
		strPath = arrTemp(0)
		For i = 1 To UBound(arrTemp)
			strCmd = strCmd & " " & Chr(34) & GetLongName(strPath & arrTemp(i)) & Chr(34)
		Next
	Else
		strCmd = strCmd & " " & Chr(34) & GetLongName(objDialog.FileName) & Chr(34)
	End If
End If 

WScript.Echo strCmd


Function GetLongName(strFileName)
' 	On Error Resume Next
	
	Dim objShell, ObjFSO, objFile, objFolder, objItem
	
	Set objShell = CreateObject("Shell.Application")
	Set ObjFSO = CreateObject("Scripting.FileSystemObject")
	Set objFile = ObjFSO.GetFile(strFileName)
	Set objFolder = objShell.NameSpace(objFile.ParentFolder.Path)
	Set objItem = objFolder.ParseName(objFile.Name)
	GetLongName = Replace(objItem.Path, objFile.ParentFolder.Path & "\", "")
' 	GetLongName = objItem.Path
End Function

--------------------------------------------------------------------------------
dm4ever
My philosophy: K.I.S.S - Keep It Simple Stupid
 
dm,
that did it.
my project is now complete.
thanks so much.
:)
 
dm,
i did some search to found out how to do multiselect from an explorer dialog. here's the code:
Code:
 ObjFSO.Flags = cdlOFNAllowMultiselect or cdlOFNExplorer
this will display explorer type dialog with correct file names and will also let you do multi select.
i have already finished my project using your function (GetLongName). and it works fine. but this code above, when selected more that one file, it only lists the path, and nothing more. just to let you know. any ideas where the file names would be on this one?
 
I was wondering how to use multiple flags because there's one for long file names. Let me take a look. If I find anything I'll post back.

--------------------------------------------------------------------------------
dm4ever
My philosophy: K.I.S.S - Keep It Simple Stupid
 
dm,
here's the code if you need to test it or do some more digging:
Code:
Const cdlOFNAllowMultiselect = 512
const cdlOFNExplorer = 524288
Set ObjFSO = CreateObject("UserAccounts.CommonDialog")
ObjFSO.Filter = "All Files|*.*"
ObjFSO.FilterIndex = 3
ObjFSO.InitialDir = "c:\"
ObjFSO.Flags = cdlOFNAllowMultiselect or cdlOFNExplorer 
InitFSO = ObjFSO.ShowOpen
selected_files = ObjFso.FileName  
If InitFSO = False Then
   msgbox "No files were selected"
else
   each_file = split(selected_files, vbnullchar)
   '----i was told the file names are delimited by null
   msgbox selected_files
end if



 
Have you tried something like this ?
For Each each_file In Split(selected_files, [!]Chr(0)[/!])
MsgBox each_file
Next

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ181-2886
 
I played around with this and did some searches and it seems using the flags cdlOFNAllowMultiselect or cdlOFNExplorer only works properly using VB6.

I saw that PrimalScript has a dll which (once registered) you can use within VBScript and it allows for multiple file selection and returns them with their long names.

At this point, it looks like those are the most direct ways to browse and retrieve file names. An alternate method could be to use Shell.Application and the browseforfolder method to select a folder, use the filesystemobject to populate a list of the file in the folder, and then display it in your HTA body for your selection.

--------------------------------------------------------------------------------
dm4ever
My philosophy: K.I.S.S - Keep It Simple Stupid
 
So here's my idea of an alternate way to select multiple files using UserAccounts.CommonDialog (to get to the directory of the files you want to select from) and FileSystemObject to display the files in the directory. It's not less code to use, but at least you can see the files you're selecting with their long names instead of the short one's. Copy code and save into an HTA.

Code:
<html>
<head>
<title>Browse For File</title>
<script language="vbscript">
	Option Explicit
' 	On Error Resume Next
	Dim strCurrDir
	
	Sub window_onload
		window.resizeTo 550, 550
		window.moveTo screen.width/4,screen.height/4
	End Sub
	
	Sub GetFiles
' 		On Error Resume Next
		
		Dim objFSO, objDlg, errRtn, strFile, strHTML, objFile, objFolder, objItem
		
		Set objFSO = CreateObject("Scripting.FileSystemObject")
		Set objDlg = CreateObject("UserAccounts.CommonDialog")
		objDlg.Filter = "VBScripts|*.vbs|Text Documents|*.txt|All Files|*.*"
		objDlg.FilterIndex = 3
		If strCurrDir = "" Or IsNull(strCurrDir) Then
			objDlg.InitialDir = "d:\temp"
		Else
			objDlg.InitialDir = strCurrDir
		End If
		errRtn = objDlg.ShowOpen()
		
		If errRtn = False Then
			alert "No file selected!"
		Else
			strFile = objDlg.FileName
		End If
		
		Set objFile = objFSO.GetFile(strFile)
		strCurrDir = objFile.ParentFolder
		Set objFolder = objFSO.GetFolder(objFile.ParentFolder)
		
		strHTML = "Files in: " & strCurrDir & "<br><select id='files' size='20' multiple>"
		For Each objItem In objFolder.Files
			strHTML = strHTML & "<option value='" & Replace(objItem.Name, "'", chr(7)) & "'>" & objItem.Name & "</option>"
		Next
		
		strHTML = strHTML & "</select><br><br>" & _
				  "<input type='button' value='Get Selected Files' onclick='GetSelFiles'>"
		window.document.getElementById("fileselection").innerHTML = strHTML
	End Sub
	
	Sub GetSelFiles
' 		On Error Resume Next
		
		Dim i, strFileName, strOutput
		
		strOutput = "createcd.exe D:"
		For i = 0 to (files.Options.Length - 1)
			If (files.Options(i).Selected) Then
				strFileName = files.Options(i).Value
				strFileName = Replace(strFileName, Chr(7), "'")
				strOutput = strOutput & " " & Chr(34) & strFileName & Chr(34)
			End If
		Next
		
		alert strOutput
	End Sub
</script>
<hta:application
	applicationname="Browse For File"	
	border="dialog"
	borderstyle="normal"
	caption="Browse For File"
	contextmenu="no"
	icon=""
	maximizebutton="no"
	minimizebutton="yes"
	navigable="no"
	scroll="no"
	selection="no"
	showintaskbar="yes"
	singleinstance="yes"
	sysmenu="yes"
	version="1.0"
	windowstate="normal"
>
</head>
<body bgcolor="#272936" style="overflow:auto;color:#FFFFFF;font-size:18px">
<div align="center">
<input type="button" value="Browse To File Location" onclick="GetFiles">
<br><br>
<span id="fileselection"></span>
</div>
</body>
</html>

--------------------------------------------------------------------------------
dm4ever
My philosophy: K.I.S.S - Keep It Simple Stupid
 
dm, thanks so much.
here's the codes that you were wondering about. for some options on the flags. you can mix them with "OR" or "+"
Const cdlOFNReadOnly = 1 ' or &H1
Const cdlOFNNoValidate = 256 ' or &H100
Const cdlOFNAllowMultiselect = 512 ' or &H200
Const cdlOFNFileMustExist = 4096 ' or &H1000
Const cdlOFNExplorer = 524288 ' or &H80000
Const cdlOFNLongNames = 2097152 ' or &H200000
Const cdlPDDisablePrintToFile = 524288
thanks so much for the knowledge.
all the examples that i've seen on this mix mode, are in vb6. i have yet to see a vbscript utilizing that. just out of curiosity, what dll needs to be registered?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top