Using file input element in hta file prevents deleting selected file

淺唱寂寞╮ 提交于 2019-12-05 20:35:23

Use a regular text input box

<input type="text" name="FileName" size="30">

Add a button to click to open the file

<input type="button" onClick="SelectFile" value="Browse...">

Add a file dialog object

<OBJECT id=Dlg classid="CLSID:3050F4E1-98B5-11CF-BB82-00AA00BDCE0B" width=0 height=0>

Add a sub to take the return value of this object and put it in your text box.

Sub SelectFile
    FileName.value = ""
    strStartPath = "C:\Test"
    strFilter = "Text (*.txt;*.csv)| *.txt;*.csv|VBScript (*.vbs;*.vbc)|*.vbs;*.vbc|HTML (*.htm;*.html;*.hta)|*.htm;*.html;*.hta|All Files (*.*)|*.*|"
    strCaption = "Select a File"
    FileName.value = Dlg.openfiledlg(CStr(strStartPath), , CStr(strFilter), CStr(strCaption))
End Sub

The strStartPath, strFilter, and strCaption variables can be excluded or customized as needed.

FileName.value will contain the path to the file and it will not be locked.

Edit:
Here's the entire HTA, excluding code to delete the file (I have tested this with the delete code):

<html>
<HEAD>
<HTA:APPLICATION
  APPLICATIONNAME="Select File"
  ID="SelectFileApplication"
  VERSION="1.0"/>
<SCRIPT Language="VBScript">

Sub SelectFile
    FileName.value = ""
    strStartPath = "C:\Test"
    strFilter = "Text (*.txt;*.csv)| *.txt;*.csv|VBScript (*.vbs;*.vbc)|*.vbs;*.vbc|HTML (*.htm;*.html;*.hta)|*.htm;*.html;*.hta|All Files (*.*)|*.*|"
    strCaption = "Select a File"
    FileName.value = Dlg.openfiledlg(CStr(strStartPath), , CStr(strFilter), CStr(strCaption))
    'The file at FileName.value can be deleted at this point.
End Sub

</SCRIPT>
</HEAD>
<body id="body">
<input type="text" name="FileName" size="30">
<input type="button" onClick="SelectFile" value="Browse...">
<OBJECT id=Dlg classid="CLSID:3050F4E1-98B5-11CF-BB82-00AA00BDCE0B" width=0 height=0>
</body>
</html>
Lankymart

Update: Based on feedback from OP

Well have now tested this approach myself with similar results to the OP so thought I'd investigate further.

The File Handle appears to be held for the life of the page, tried the following

  • Encapsulating in a <form> then calling Reset() method
  • Clearing the <input> value attribute and using a variable to hold the file path.

Neither work but while tested realised that if you refresh the page inside the HTA the file deletion occurs, this means that forcing the page to reload should work, so ended up doing just that.

<html>
<HEAD>
<HTA:APPLICATION ID="oHTA"
     APPLICATIONNAME="myApp"
     BORDER="thin"
     BORDERSTYLE="normal"
     CAPTION="yes"
     ICON=""
     MAXIMIZEBUTTON="yes"
     MINIMIZEBUTTON="yes"
     SHOWINTASKBAR="no"
     SINGLEINSTANCE="no"
     SYSMENU="yes"
     VERSION="1.0"
     WINDOWSTATE="normal"/>
<SCRIPT Language="VBScript">
Sub Process
    Set x = CreateObject("Scripting.FileSystemObject")
    MsgBox "try to manually delete "& INIFile.Value &" (and then undo it)"
    x.DeleteFile INIFile.Value
    'Reload page
    Call window.location.reload()
End Sub
</SCRIPT>
</HEAD>
<body id='body'>
<input type="file" name="INIFile" >
<input type="button" value="Go!" onClick="Process" >
</body>
</html>

which works, obviously this isn't ideal for capturing the fact the file has been deleted as the page is reloaded but the OP hasn't gone into detail as to their requirement.

You could also make the the Go button a <input type="submit"> and use the OnSubmit event to call Process() which might be cleaner approach then calling window.location.reload().

Further Update:

From testing with multiple files have noticed that once another file is selected using the <input type="file"> the previous file is deleted as the handle is released and given to the newly selected file.

I wonder if cloning the <input type="file"> element and removing the previous one will have the same effect and avoid needing to reload the page?


Update: Have since tested and does still hold on to the File Handle

The <input type="file"> is designed for uploading files so it makes sense that once you have selected a file the HTA holds a handle open to it. That being said, there is no reason why you have to call the value of INIFile directly instead store it in a variable (after all it's just a string) and then clear the Value attribute of the <input>.

Sub Process
    Dim x: Set x = CreateObject("Scripting.FileSystemObject")
    'Get file path from INPUT
    Dim file: file = INIFile.Value
    'Reset file INPUT
    INIFile.Value = ""
    MsgBox "this will actually delete "& file
    x.DeleteFile file
    MsgBox "see? "& file &" is gone"
    Set x = Nothing
End Sub

Useful Links

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!