我正在构建一个供个人使用的小HTA,并且希望能够将文件拖放到界面中。删除文件后,我会自动运行它(假设它适合我设置的一些参数,如文件扩展名),或者至少填写HTA界面上的输入框。
我进行了广泛的搜索,但无法找到解决方案。想法?
答案 0 :(得分:5)
启动HTA后,它会查看您是否已配置DropHandler。如果不这样做,它为您提供了为您配置它的选项。配置好后,你需要做的就是关闭并重新打开HTA和wallah,你可以在HTA文件中使用Drag and Drop支持。
答案 1 :(得分:1)
如果您不想启用放置处理程序,我可以想象一种可能的方法。这是一个喜剧链,但我可以看到自己实现这个,如果我被支持到一个角落,需要这个功能。
您可以创建一个IFRAME,其src作为临时文件夹。此文件夹将显示为资源管理器视图。然后,您可以将文件拖入其中。针对该文件夹设置轮询例程以查看是否有任何新文件。瞧,你有一种蹩脚的方式来支持给定文件的拖放操作。
答案 2 :(得分:0)
去尝试谷歌齿轮,它们提供拖放功能。
你甚至可以在hta中使用mysql。
Google Gears在hta中不可用,但是,您可以在html文件中创建activexobject,然后使用iframe(<iframe application="true" src=".."></iframe>)
之后,您可以使用activexobject
到iframe
。
答案 3 :(得分:0)
关于......
“希望能够将文件拖放到[HTA]界面”
...我将其解释为希望将文件拖放到HTA的运行窗口,而不是删除HTA文件本身的文件或快捷方式。
使用HTML5,删除本身很容易。使用例如一个<div>
元素作为放置区域。对于此元素,处理事件dragenter
,dragover
和drop
。例如。 drop handler可以如下所示:
function on_drop( e )
{
e.preventDefault(); // stops the browser from redirecting off to the file
var dt = e.dataTransfer
var is_file_transfer = false;
for( var i = 0; i < dt.types.length; ++i )
{
if( dt.types[i].toLowerCase() == 'files' )
{
is_file_transfer = true;
}
}
if( !is_file_transfer )
{
return false;
}
on_files_dropped( dt.files );
return true;
}
...其中on_files_dropped
是由您定义的处理文件丢弃的函数。
在文档加载事件中动态添加事件处理程序,如下所示:
var dropbox = document.getElementById( 'blah' );
dropbox.addEventListener( 'dragenter', on_dragenter, false );
dropbox.addEventListener( 'dragover', on_dragover, false );
dropbox.addEventListener( 'drop', on_drop, false );
到目前为止一切顺利。
但是,安全性会受到限制:您无法直接了解原始文件路径,只知道文件名和文件大小。此功能是为Web而设计的,而不是为本地受信任的HTML应用程序设计的。所以它可能是也可能不一定是个问题。
为了将已删除的文件用作HTML元素的源,并且通常用于读取已删除的文件,HTML5提供 FileReader
(有许多tutorials可用,它们与技术文档相关联。)
需要本地路径,例如要在Windows Mediaplayer中播放文件,您可以假设拖动操作源自Windows资源管理器,现在也称为文件资源管理器,然后只检查哪个资源管理器窗口(如果有)包含具有该名称的文件和大小。
希望不会找到一个这样的原始窗口。
var shell = new ActiveXObject( "Shell.Application" );
var fso = new ActiveXObject( "Scripting.FileSystemObject" );
function possible_paths_for( filename )
{
var windows = shell.windows(); // Windows Explorer windows.
var n_windows = windows.Count;
var lowercase_filename = filename.toLowerCase();
var paths = Array();
for( var i = 0; i < n_windows; ++i )
{
var url = windows.Item(i).LocationURL;
var path = decodeURI( url.substr( 8 ) ).replace( /\//g, '\\' );
// The path can be the path of this HTML application (.hta file), so:
if( fso.FolderExists( path ) )
{
var folder = fso.GetFolder( path );
for( var it = new Enumerator( folder.Files ); !it.atEnd(); it.moveNext() )
{
var file = it.item();
if( file.Name.toLowerCase() == lowercase_filename )
{
paths.push( file.Path.toLowerCase() );
}
}
}
}
return paths;
}
基本上就是这样。也许,因为HTA默认为IE7,如何获得HTML5功能。好吧可以通过doctype声明,但到目前为止,在我的小实验中,我只使用以下内容:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<!-- A windows web control defaults to quirky IE7 semantics. Request for better: -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="MSThemeCompatible" content="yes">
这为您提供了最新的Internet Explorer引擎,但代价是没有HTA
元素,因此无法直接访问命令行。我发现the command line can be retrieved by running Windows’ wmic
program,但这是一个可怕的黑客。整个问题领域,大多数明显开放的道路都被关闭,似乎是微软现在考虑HTA的结果a legacy technology, to be quietly phased out in favor of fullscreen ad-ridden Windows 8 AppStore apps。
无论如何,祝你好运!
答案 4 :(得分:0)
我可以确认可以使用“ Web浏览器”在HTA窗口中获得文件和文件夹的拖放功能(无需使用任何第三方ActiveX对象,HTML5或带有注册表)。
默认情况下,自XP或2000开始,在每个Windows中都内置了“ Web浏览器”本身时,打开了“ RegisterAsDropTarget”参数即可进行此类操作。这样,它适用于以任何语言环境命名的输入文件(支持Unicode名称),例如,WScript和CScript默认情况下不支持此文件。
下面是一个实现为自包含组件的示例,具有许多自定义功能,包括样式和背景。它适用于64位和32位文件夹路径,并且可以插入某些窗口的DOM树中。
将下面的源代码保存为文本文件,然后将其扩展名更改为“ hta”。 然后双击获得的应用程序。
<script>
/*
Extended Drop Target v1.1.4 (https://tastyscriptsforfree.wix.com/page/scripts)
Copyright 2017-2020 Vladimir Samarets. All rights reserved.
tastyscriptsforfree@protonmail.com
Release date: November 9, 2020.
Use this script sample entirely at your own risk.
This script sample is copyrighted freeware and I am not responsible for any damage or data loss it could unintentionally cause.
You may modify it but please leave a comment with direct link to https://tastyscriptsforfree.wix.com/page/scripts in that case.
*/
offscreenBuffering = true; //postpone the application window appearance till its UI is ready
var O = function(o){return new ActiveXObject(o);},
WSS = O('WScript.Shell'),
env = WSS.Environment('Process'),
head = document.documentElement.firstChild, //head
PID; //PID of 64 bit HTA instance
if(!env('is64bit')) //indicates whether the application is launched as 64 bit or not
{
!function hide(e){try{moveTo(10000, 10000);}catch(e){try{hide();}catch(e){hide();}}}(); //hiding the application window
head.insertBefore(document.createElement('<hta:application showInTaskBar=0>'), head.firstChild); //hiding the application in the Taskbar
var WMI= //a small library written by me for obtaining WMI instance, its common methods and properties
{ //below is a sample of creating a process with certain window shifts and environment variables
//and obtaining its <ProcessId> by using WMI
SWL:new ActiveXObject('WbemScripting.SWbemLocator'),
PRMS:function(p)
{
var s = WMI.PS.SpawnInstance_();
for(var i in p)
s[i] = p[i];
return s;
},
Create:function(c, s, d)
{
var CreateIn = WMI.CreateIn.SpawnInstance_();
CreateIn.CommandLine = c;
CreateIn.ProcessStartupInformation = s;
CreateIn.CurrentDirectory = d;
return WMI.PRC.ExecMethod_('Create', CreateIn).ProcessId;
}
};
WMI.PRC = (WMI.WM = WMI.SWL.ConnectServer('.', 'root/cimv2')).Get('Win32_Process');
WMI.PS = WMI.WM.Get('Win32_ProcessStartup');
WMI.CreateIn = WMI.PRC.Methods_('Create').InParameters;
var ID = O('Scriptlet.TypeLib').GUID.substr(0, 38), //the unique ID obtaining
EV = 'is64bit='+ID; //passing the unique ID to 64 bit HTA instance as an Environment variable
for(var items = new Enumerator(env); !items.atEnd(); items.moveNext())
EV += '?' + items.item(); //obtaining all Environment variables for current process
PID = WMI.Create //obtaining PID of 64 bit HTA instance
(
'mshta "' + decodeURIComponent(location.pathname) + '"', //current path
WMI.PRMS
(
{
X:10000, Y:10000, //hiding the application window before it is shown in order to resize it smoothly
EnvironmentVariables:
EV.split('?') //obtaining an array of all Environment variables by using this approach is universal for different
//versions of Windows
/*
[ //another way to pass certain Environment variables
'is64bit='+ID, //indicates that the application is launched as 64 bit
'SystemRoot='+env('SystemRoot'), //for start
'SystemDrive='+env('SystemDrive'), //for hyperlinks
'TEMP='+env('TEMP'), //for "mailto" links
'CommonProgramW6432='+env('CommonProgramW6432') //for ADODB.Stream
]
*/
}
)
);
head.firstChild.insertAdjacentHTML('afterEnd', '<object id=' + ID + ' PID=' + PID +
' classid=clsid:8856F961-340A-11D0-A96B-00C04FD705A2><param name=RegisterAsBrowser value=1>'); //registering current HTA window in collection of windows
showModalDialog('javascript:for(var ws=new ActiveXObject("Shell.Application").Windows(),i=ws.Count;i-->0;)if((w=ws.Item(i))&&w.id=="'+ID+'"){w.s=document.Script;break;}', 0,
'dialogWidth:0;unadorned:1;'); //silent stop of the script and obtaining window focus for "AppActivate"
close();onerror=function(){close();};throw 0; //declining any further attempts of executing the rest statements of the code
}
var w,dt=new Date();
head.insertBefore(document.createElement('<hta:application contextMenu=no selection=no scroll=no>'), head.firstChild); //adding custom HTA header dynamically
document.title='Extended Drop Target';
resizeTo(800, 400);
for(var ws = O('Shell.Application').Windows(), i = ws.Count; i -- > 0;)
if((w = ws.Item(i)) && w.id == env('is64bit'))
{
PID = w.PID;
w.document.Script.WSS.AppActivate(PID); //using "WScript.Shell" in focus to activate
//the application window of 64 bit HTA instance;
//remember that "WScript.Shell" should be
//in focus in order "AppActivate" to work properly
break;
}
document.write('<body>'); //obtaining body
if(w && w.id == env('is64bit'))
w.s.close(); //closing previous 32 bit HTA instance while being in safe focus
document.body.appendChild(document.createTextNode('Debug screen (for test purposes only):'));
document.body.appendChild(document.createElement('br'));
document.body.appendChild(document.createElement('<textarea id=result cols=85 rows=5>'));
document.body.appendChild(document.createElement('p'));
document.body.appendChild(document.createTextNode('Extended Drop Target:'));
document.body.appendChild(document.createElement('br'));
document.body.appendChild
(
(
function createDropTarget(doc, filesAllowed, foldersAllowed, dTStyle, hdFont, wMColor, dMColor, pMColor, eMColor, process, resolve, msg, dBgImage, bBgImage,
description, redirect)
{
var dropTarget = doc.createElement('<span style="' + dTStyle + '">'),
ms = dropTarget.appendChild
(
doc.createElement('<span style="width:100%;height:100%;padding:10px;overflow:hidden;">')
), //message screen that hides Web Browser during dropped items processing
WB = '<object classid=clsid:8856F961-340A-11D0-A96B-00C04FD705A2 style="width:100%;height:100%;"><param name=Location value="about:<body onload=\'b=0;\'' +
' ondragover=(function(){clearTimeout(b);b=setTimeout(\'location.reload();\',100);}()) bgColor=' + dMColor +
' style=\'width:100%;height:100%;position:absolute;margin:0;border:0;overflow:hidden;\'>'+ (description || '') +'">',
processing = 1, //indicates whether a dropped item processing is started or not
processed = 1, //indicates whether a dropped item is processed or not
DBcatched = 1, //indicates whether DownloadBegin Web Browser event has been catched or not
allowed, //indicates whether drop target is allowed or not
allowedText = (filesAllowed ? foldersAllowed ? msg[32] : msg[33] : foldersAllowed ? msg[34] : ''), //"Drop a file or folder here."
WBTReset, //timeout for Web Browser reset
startProcessing = function(p) //processing the item path received after item drop (item path)
{
clearTimeout(WBTReset);
dropTarget.children[processed = 1].removeNode();
createDropTarget();
setTimeout(function()
{
var delay = 0;
if(p) //the item can be accessed
{
sM(msg[38] + p + '</div>', pMColor); //show "Processing"
var dt = new Date(), //date before processing
e; //error ID
try{e = process(p);}catch(e){e = 43;} //unknown error occured
dt = new Date() - dt; //date after processing
delay += dt>1000 ? 0 : 1000 - dt;
if(!e) //no errors occured
setTimeout(function(){sM(msg[39] + createDropTarget.timeToHMSR(dt) + ' =-</div>', pMColor);}, delay); //show "Processed in"
else //an error occured
{
var err;
try{resolve(e);}catch(err){;}
setTimeout(function(){sM(msg[39] + createDropTarget.timeToHMSR(dt) + ' =-</div><br>' + msg[e], eMColor);}, delay); //show "Processed in" with error
if(!redirect)
delay += 1000;
}
}
else //the item can't be accessed
{
sM(msg[40] + msg[41] + allowedText + msg[42], eMColor); //show "The item is not a file or folder, can't be accessed or its size is too big."
delay += 1000;
}
sDM(delay + 1000);
}, 1000);
},
setWBTReset = function(r) //setting a timeout for Web Browser reset (reset)
{
if(!processing)
{
processing = 1;
ms.style.display = '';
if(r)
WBTReset = setTimeout(startProcessing, 1000);
}
},
DB = function() //catching "DownloadBegin" Web Browser event
{
DBcatched = 1;
setWBTReset(1);
},
STC = function(p) //catching "StatusTextChange" Web Browser event (item path)
{
setWBTReset(p);
if(!processed && /file:|</.test(p))
{
if(/file:/.test(p))
startProcessing(filesAllowed ? decodeURIComponent(p).replace(/.+:((?:\/{3})|(?=\/{2}))(.+)...$/,'$2').replace(/\//g,'\\') : 0);
else if(/</.test(p))
{
if(!DBcatched) //indicates that drop target is leaved without drop
{
processed = 1;
clearTimeout(WBTReset);
sM(msg[31] + allowedText + msg[35] + '</div>', dMColor, dBgImage); //show "Drop a file or folder here."
allowed = 1;
ms.style.display = '';
}
else //shortcuts with complex structure
startProcessing();
}
}
},
NC2 = function(o, p) //catching "NavigateComplete2" Web Browser event (Web Browser object, item path)
{
if(!processed)
startProcessing(foldersAllowed && typeof p == 'string' && p.match(/^[^:]/) ? p : 0);
},
NE = function() //catching "NavigateError" Web Browser event
{
if(!processed)
startProcessing();
},
sM = function(m, c, bgImage) //show message (message, background or text color, background image)
{
if(dBgImage || bBgImage)
{
if(bgImage)
ms.style.backgroundImage = 'url(' + bgImage + ')';
ms.style.color = c;
}
else
ms.style.backgroundColor = c;
m = '<div style="font:' + hdFont + ';">' + m;
if(!redirect)
ms.innerHTML = m;
else
redirect(m);
},
sDM = function(delay) //show default message (delay)
{
setTimeout(function(){allowed = 1;}, delay);
setTimeout(function(){if(allowed)sM((allowedText ? msg[31] + allowedText + msg[35] : msg[36]) + '</div>', dMColor, dBgImage);}, delay + 100); //show "Drop a file or folder
//here." or "Drop Target is
} //disabled."
sM(msg[30], wMColor, dBgImage); //show welcome message
ms.ondragenter=function()
{
if(allowed && (filesAllowed || foldersAllowed) && !event.dataTransfer.getData('text')) //text dropping is not allowed
{
event.dataTransfer.dropEffect='move';
return false;
}
}
ms.ondragover = function()
{
if(allowed && (filesAllowed || foldersAllowed) && !event.dataTransfer.getData('text')) //text dropping is not allowed
{
event.dataTransfer.dropEffect='move';
if(!Math.abs(event.x - this.x) && !Math.abs(event.y - this.y)) //accepting only slow mouse motion
{
this.style.display = 'none';
DBcatched = allowed = processing = processed = 0;
sM(msg[37], dMColor, bBgImage); //show "Analysing..."
}
this.x = event.x;
this.y = event.y;
return false;
}
}
!(createDropTarget = function()
{
dropTarget.insertAdjacentHTML('beforeEnd', WB);
with(dropTarget.children[1])
{
RegisterAsDropTarget = Silent = Offline = 1;
attachEvent('DownloadBegin', DB);
attachEvent('StatusTextChange', STC);
attachEvent('NavigateComplete2', NC2);
attachEvent('NavigateError', NE);
}
})();
createDropTarget.timeToHMSR = function(d) //convert date to hours, minutes, seconds and remainder (milliseconds) notation (date)
{
var r = d % 3600000,
h = d / 3600000 ^ 0, //hours
m = r / 60000 ^ 0, //minutes
s = r % 60000 / 1000 ^ 0; //seconds
r = d % 1000; //remainder (milliseconds)
return ((h ? h + 'h' : '') + (m ? (h ? ' ' : '') + m + 'm' : '') + (s ? (h || m ? ' ' : '') + s + 's' : '') + (r ? (h || m || s ? ' ' : '') + r + 'ms' : '')) || '0ms';
},
sDM(3000); //postponing Web Browser access while it generates its events at start
return dropTarget;
}
(
//BEGIN of Extended Drop Target custom settings
document, //"document" object of certain window
1, //indicates whether processing of files is allowed or not
1, //indicates whether processing of folders is allowed or not
'width:350px;height:150px;border:2px blue solid;font:bold 10pt Arial;text-align:center;cursor:default;overflow:hidden;word-break:break-all;', //drop target style
'bold 12pt Tahoma', //message header font
'yellow', //welcome message background color if background image is not set or text color otherwise
'mediumaquamarine', //default message background color if background image is not set or text color otherwise
'limegreen', //processing message background color if background image is not set or text color otherwise
'salmon', //error message background color if background image is not set or text color otherwise
function(p) //data processing sample (file or folder path)
{
alert('Here goes data processing sample.\n\nProcessing:\n' + p);
//throw 1; //unknown error occured
//return 1; //certain error 1 occured
return 0; //no errors
},
function(e) //error resolving sample (error ID)
{
switch(e)
{
case 1:
result.value = '\nCertain error 1 is catched.'; //additional action sample for certain error 1
updateData1();
break;
default:
result.value = '\nAn unknown error is catched.'; //additional action sample for an unknown error
sendEmail();
break;
}
file.Close(); //built-in silent catching of errors if certain error resolving method is still inaccessible
},
{ //list of all messages for Extended Drop Target
30: 'Welcome!</div><br>Hello World!', //welcome message
31: 'Drop a ', //31, 32, 33, 34, 35 - "Drop a file or folder here."
32: 'file or folder',
33: 'file',
34: 'folder',
35: ' here.',
36: 'Drop Target is disabled.',
37: '-= Analysing... =-</div>',
38: '-= Processing =-</div><br><div style="text-align:left;">',
39: '-= Processed in ',
40: "-= Can't be processed =-</div><br>",
41: 'The item is not a ', //41, 32, 33, 34, 42 - "The item is not a file or folder,<br>can't be accessed or its size is too big."
42: ",<br>can't be accessed or its size is too big.",
43: 'An unknown error occured.', //unknown error message
1: 'Certain error 1 occured.' //certain error 1 message
//certain error # message
//...
}
//,'C:\\Windows\\Web\\Screen\\img103.png' //default background image or "undefined" (optional)
//,'C:\\Windows\\Web\\Screen\\img102.jpg' //busy mode background image or "undefined" (optional)
//,'<div style=\'font:10pt Tahoma;padding:20px;\'>List of files supported by default.</div>'
//description length depends on the message language or its actual bytes count or "undefined" (optional)
//,function(m){result.value = m;} //sample for receiving messages or "undefined" (optional)
//END of Extended Drop Target custom settings
)
)
);
result.value = '\nLoading time for 64 bit instance (if possible): ' + createDropTarget.timeToHMSR(new Date() - dt) + '.';
moveTo(screen.availWidth / 2 - 400, screen.availHeight / 2 - 200);
</script>
答案 5 :(得分:-2)
HTA显然不能成为shell drop操作的目标 - 至少在我的系统上,在HTA上丢弃一些东西是不可能的。
这意味着你不能直接做你想做的事。
然而.vbs可以是放弃目标。可以通过WScript.Arguments.Unnamed
集合获取已删除文件的完整路径。
HTA可以通过the commandLine Property访问它的命令行参数。这意味着您可以构建一个小帮助程序VBScript,将已删除的文件转换为命令行并为您调用HTA。
请注意,您不能在.vbs上删除无限量的文件,并且命令行也不是无限制的。在几KB的范围内将有一个长度限制(我没有试图找到确切的限制,只是准备面对一个限制。)