在 hta 文件中使用文件输入元素可防止删除所选文件
Using file input element in hta file prevents deleting selected file
如果 type=file 的输入 html 元素用于 select 文件,则 hta 程序无法删除该文件。
此 MVCE 有效但不使用文件对话框 - 您必须手动输入文件名:
<html>
<HEAD>
<SCRIPT Language="VBScript">
Sub Process
Set x = CreateObject("Scripting.FileSystemObject")
MsgBox "this will actually delete "& INIFile.Value
x.DeleteFile INIFile.Value
MsgBox "see? "& INIFile.Value &" is gone"
Set x = Nothing
End Sub
</SCRIPT>
</HEAD>
<body id='body'>
<input type="text" name="INIFile" >
<input type="button" value="Go!" onClick="Process" >
</body>
</html>
但是这个 MVCE 不起作用 - 文件没有被删除;只是推迟到程序退出:
<html>
<HEAD>
<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
MsgBox "now try to delete file "& INIFile.Value &" (now it can't be deleted until the app is closed)"
Set x = Nothing
End Sub
</SCRIPT>
</HEAD>
<body id='body'>
<input type="file" name="INIFile" >
<input type="button" value="Go!" onClick="Process" >
</body>
</html>
不知何故使用文件类型输入 html 元素使得可以从程序外部手动删除文件,直到调用 DeleteFile 函数。 DeleteFile 函数实际上并不删除文件 - 它只是将删除操作推迟到 hta 程序退出 - 此时文件最终会自行删除。
我需要在程序还在运行时删除文件。有什么方法可以在 hta 文件中使用文件类型输入 html 元素并在 hta 程序为 运行 时仍然删除文件?
编辑
我的实际用例!在尝试生成可用的 MVCE 时,我没有意识到会找到一个不符合我的特定要求的解决方案。
我删除文件的原因是我可以用其他东西替换它,所以我需要文件在函数结束前消失。 Call window.location.reload()
绝对有效,但文件在函数结束时消失。
我实际上想做的是这样的:
<HTML>
<HEAD>
<SCRIPT Language="VBScript">
Sub Process
Dim file: file = INIFile.Value
Call window.location.reload()
'backup the file to tempfile.tmp
'Now edit tempfile.tmp with all the changes and preview it
'then ask the user whether they are happy with the changes
'delete the original file
'and put the tempfile.tmp in its place
Dim x: Set x = CreateObject("Scripting.FileSystemObject")
x.CopyFile file,"tempfile.tmp"
x.DeleteFile file
MsgBox "why is "& file &" still there?"
x.MoveFile "tempfile.tmp",file ' this produces "file already exists"
Set x = Nothing
End Sub
</SCRIPT>
</HEAD>
<BODY id='body'>
<INPUT type="file" name="INIFile" onChange="Process">
</BODY>
</HTML>
更新: 基于
现在我自己测试了这种方法,结果与 OP 相似,所以我想我会进一步调查。
文件句柄似乎在页面的整个生命周期内都被保留,尝试了以下方法
- 封装在
<form>
然后调用Reset()
方法
- 清除
<input>
value
属性并使用变量保存文件路径。
两者都不起作用,但在测试时发现,如果您在 HTA 中刷新页面,则会发生文件删除,这意味着强制重新加载页面应该可行,所以最终就这样做了。
<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>
有效,显然这对于捕获文件已在重新加载页面时被删除但 OP 没有详细说明他们的要求这一事实来说并不理想。
您还可以将 Go
按钮设为 <input type="submit">
并使用 OnSubmit
事件来调用 Process()
,这可能比调用 window.location.reload()
更简洁].
进一步更新:
从对多个文件的测试中注意到,一旦使用 <input type="file">
选择另一个文件,随着句柄被释放并提供给新选择的文件,前一个文件将被删除。
我想知道克隆 <input type="file">
元素和删除前一个元素是否会产生相同的效果并避免重新加载页面?
Update: Have since tested and does still hold on to the File Handle
<input type="file">
是为上传文件而设计的,因此一旦您选择了一个文件,HTA 就会持有一个打开它的句柄。话虽如此,你没有理由必须直接调用 INIFile
的值而不是将其存储在变量 (毕竟它只是一个字符串) 然后清除Value
<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
有用的链接
- How do you set file input to nothing with JavaScript or HTML?
使用常规文本输入框
<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>
添加一个子项以获取此对象的 return 值并将其放入您的文本框中。
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
可以根据需要排除或自定义 strStartPath、strFilter 和 strCaption 变量。
FileName.value 将包含文件的路径并且不会被锁定。
编辑:
这是整个 HTA,不包括删除文件的代码(我已经用删除代码测试了它):
<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>
如果 type=file 的输入 html 元素用于 select 文件,则 hta 程序无法删除该文件。
此 MVCE 有效但不使用文件对话框 - 您必须手动输入文件名:
<html>
<HEAD>
<SCRIPT Language="VBScript">
Sub Process
Set x = CreateObject("Scripting.FileSystemObject")
MsgBox "this will actually delete "& INIFile.Value
x.DeleteFile INIFile.Value
MsgBox "see? "& INIFile.Value &" is gone"
Set x = Nothing
End Sub
</SCRIPT>
</HEAD>
<body id='body'>
<input type="text" name="INIFile" >
<input type="button" value="Go!" onClick="Process" >
</body>
</html>
但是这个 MVCE 不起作用 - 文件没有被删除;只是推迟到程序退出:
<html>
<HEAD>
<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
MsgBox "now try to delete file "& INIFile.Value &" (now it can't be deleted until the app is closed)"
Set x = Nothing
End Sub
</SCRIPT>
</HEAD>
<body id='body'>
<input type="file" name="INIFile" >
<input type="button" value="Go!" onClick="Process" >
</body>
</html>
不知何故使用文件类型输入 html 元素使得可以从程序外部手动删除文件,直到调用 DeleteFile 函数。 DeleteFile 函数实际上并不删除文件 - 它只是将删除操作推迟到 hta 程序退出 - 此时文件最终会自行删除。
我需要在程序还在运行时删除文件。有什么方法可以在 hta 文件中使用文件类型输入 html 元素并在 hta 程序为 运行 时仍然删除文件?
编辑
我的实际用例!在尝试生成可用的 MVCE 时,我没有意识到会找到一个不符合我的特定要求的解决方案。
我删除文件的原因是我可以用其他东西替换它,所以我需要文件在函数结束前消失。 Call window.location.reload()
绝对有效,但文件在函数结束时消失。
我实际上想做的是这样的:
<HTML>
<HEAD>
<SCRIPT Language="VBScript">
Sub Process
Dim file: file = INIFile.Value
Call window.location.reload()
'backup the file to tempfile.tmp
'Now edit tempfile.tmp with all the changes and preview it
'then ask the user whether they are happy with the changes
'delete the original file
'and put the tempfile.tmp in its place
Dim x: Set x = CreateObject("Scripting.FileSystemObject")
x.CopyFile file,"tempfile.tmp"
x.DeleteFile file
MsgBox "why is "& file &" still there?"
x.MoveFile "tempfile.tmp",file ' this produces "file already exists"
Set x = Nothing
End Sub
</SCRIPT>
</HEAD>
<BODY id='body'>
<INPUT type="file" name="INIFile" onChange="Process">
</BODY>
</HTML>
更新: 基于
现在我自己测试了这种方法,结果与 OP 相似,所以我想我会进一步调查。
文件句柄似乎在页面的整个生命周期内都被保留,尝试了以下方法
- 封装在
<form>
然后调用Reset()
方法 - 清除
<input>
value
属性并使用变量保存文件路径。
两者都不起作用,但在测试时发现,如果您在 HTA 中刷新页面,则会发生文件删除,这意味着强制重新加载页面应该可行,所以最终就这样做了。
<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>
有效,显然这对于捕获文件已在重新加载页面时被删除但 OP 没有详细说明他们的要求这一事实来说并不理想。
您还可以将 Go
按钮设为 <input type="submit">
并使用 OnSubmit
事件来调用 Process()
,这可能比调用 window.location.reload()
更简洁].
进一步更新:
从对多个文件的测试中注意到,一旦使用 <input type="file">
选择另一个文件,随着句柄被释放并提供给新选择的文件,前一个文件将被删除。
我想知道克隆 <input type="file">
元素和删除前一个元素是否会产生相同的效果并避免重新加载页面?
Update: Have since tested and does still hold on to the File Handle
<input type="file">
是为上传文件而设计的,因此一旦您选择了一个文件,HTA 就会持有一个打开它的句柄。话虽如此,你没有理由必须直接调用 INIFile
的值而不是将其存储在变量 (毕竟它只是一个字符串) 然后清除Value
<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
有用的链接
- How do you set file input to nothing with JavaScript or HTML?
使用常规文本输入框
<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>
添加一个子项以获取此对象的 return 值并将其放入您的文本框中。
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
可以根据需要排除或自定义 strStartPath、strFilter 和 strCaption 变量。
FileName.value 将包含文件的路径并且不会被锁定。
编辑:
这是整个 HTA,不包括删除文件的代码(我已经用删除代码测试了它):
<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>