怎么在html中运行exe程序
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么在html中运行exe程序相关的知识,希望对你有一定的参考价值。
参考技术A 打开html文件要用IE 然后这个文件被IE打开后页面上显示的几个类似桌面快捷方式的图标或者超链接样子的字体,然后点击其中一个,就会启动一个本地的程序
给你个例子 你回去研究吧
用HTML应用启动CD
本文介绍一种用HTML应用来启动CD的方法。HTML应用即HTML Application,也称为HTA应用,这是一种从IE 5.0开始出现的应用形式。HTML应用与普通HTML页面不同,它能够读写文件系统和注册表,由于它在本地运行,所以能够调用各种COM组件——即使COM组件没有适当的安全标记也可以。HTML应用运行时不会显示出IE的工具条和菜单,所以它看起来不象Web页面,而是象一个“真正的”程序。
一个设计专业、精美的CD启动器能够给用户留下良好的印象。启动程序可以为用户提供软件安装和光盘内容的说明,提供帮助,检查必要的第三方软件和对操作系统的要求,甚至还可以乘机向用户推荐你的其他产品,最重要的是,启动程序能够简化软件安装过程。Microsoft把支持CD“自动播放”作为兼容“Designed for Windows”标记的必备功能,软件易用性的重要程度由此可见一斑。
一、CD的启动方式
支持CD“自动播放”的启动器有多种实现方法,除了HTA,至少还包括:
▲ 编写一个简单的Visual Basic程序。采用这种方式的主要问题在于,目标系统上必须有VB运行库。虽然可以用临时安装VB运行库的办法解决,但这种方法看起来比较笨拙。
▲ 直接启动CD上软件的主安装程序(下面我们称之为setup.exe)。如果不想提供帮助信息、产品说明以及检查目标环境是否符合要求,直接启动setup.exe也是一种选择。
▲ 使用商业启动程序。有不少商业的(以及共享的)产品能够创建CD启动器。采用这种方式与自己编写HTA一样有许多优点,但采用商业产品要求你花时间了解该产品,同时还要有一定的投资。如果采用HTML应用,你可以方便地运用HTML、脚本代码构造用户界面,运用COM组件扩展HTA的功能。
▲ 使用HTML文件。HTML文件不能读写注册表,而且它在启动主安装程序时会引起安全警告。
对于要求不高的场合,软件安装过程完全可以由HTA应用独立完成,不再需要主安装程序。
二、AUTORUN.INF文件
要让CD具有自动播放功能,CD的根目录下必须有一个AUTORUN.INF文件,内容如下:
[autorun]
OPEN=<要求运行的执行文件>
ICON=<在Windows资源管理器中显示的图标>
如果不想显示图标,可以忽略ICON这一项。Windows的自动播放功能不调用Win32 ShellExecute() API,因此在OPEN这一项中只能填.exe、.com或.bat文件。因为我们想用.hta文件,这是一个小麻烦。不过解决办法很简单,只需创建一个调用ShellExecute()的autorun.exe文件就可以了。
autorun.exe是一个stub程序,它有一个命令行参数——要求运行的文件名字。例如,如果要求autorun.exe启动autorun.hta应用,在AUTORUN.INF文件中指定“OPEN=autorun.exe autorun.hta”即可。
如果ShellExecute()函数返回错误,autorun.exe在资源管理器中打开CD根目录。
下面就是AUTORUN.EXE的源代码,用VC ++ 6.0编译只有36K(可以使用其他任何Windows的C编译器):
#include <windows.h>
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
HINSTANCE result;
// 启动命令行指定的文件
result = ShellExecute(NULL, "open", lpCmdLine, NULL, NULL, SW_SHOWNORMAL);
// 检查结果
if ((int)result <= 32)
// 运行HTA文件出现错误,可能是由于
// 该机器上没有IE 5或更高版本
// 打开资源管理器,显示CD内容
ShellExecute(NULL, "explore", "", NULL, NULL, SW_SHOWNORMAL);
return 1;
else
// 启动成功
return 0;
三、常见的任务
除了显示用户界面、与用户交互以外,CD启动器可能需要执行的任务还包括:
1、启动一个Windows Installer的安装程序(MSI)。假设安装程序是setup.msi,用VBScript实现的代码如下:
作者:222.183.164.*2005-4-13 09:46 回复此发言
--------------------------------------------------------------------------------
2 用HTML应用启动CD
set msi = CreateObject( "WindowsInstaller.Installer" )
msi.InstallProduct("setup.msi")
set msi = nothing
2、启动一个EXE文件。参见本文后面的例子。
3、读取注册表内容。
有时候需要检查目标机器上是否已经安装了必要的支持软件,这可以通过检查注册表中是否有相应的ProgID来实现。以Access 2002为例,它的ProgID是Access.Application.10。下面是检查目标系统上是否已经有Access 2002的VBScript代码:
On Error Resume Next
set wscript = CreateObject("WScript.Shell")
if IsNull(wscript.regRead ( "HKCR\Access.Application.10\clsid\" )) then
msAccessDetect.InnerText = "不能找到Access 2002。你需要安装Access 2000才能运行本软件。"
else
msAccessDetect.InnerText = "已找到Access 2002。"
end if
set wscript = Nothing
如果用户禁止运行脚本(在浏览器选项中选择了禁用脚本选项),会出现什么样的情形呢?我试验了一下,什么异常也没有出现。看来HTML应用忽略了Internet安全设置,因为HTML应用被视为“本地”应用,不受Internet安全设置的限制。
四、应用实例
图一是一个CD启动器的实例。窗口布局用HTML代码实现。主要包括:用背景图片把整个窗口分成左右两大区域,左边上方是待安装的软件名称(“工资软件 Access版”),左边下方是一个广告。右边是主显示区域,显示内容由VBScript脚本更新。
图一
HTML应用的编写方式与编写HTML页面很相似,但扩展名要改为.hta。HTML应用允许通过HTA:Application标记控制应用的行为,这个标记必须在<HEAD>之内,例如,下面的HTA:Application声明了HTML应用的名称,关闭了最大化、最小化按钮,关闭了浏览器的滚动条:
<HEAD>
<TITLE>欢迎</TITLE>
<HTA:APPLICATION APPLICATIONNAME="CD Launcher"
MAXIMIZEBUTTON="no" MINIMIZEBUTTON="no"
SINGLEINSTANCE="yes" SCROLL="no" />
</HEAD>
脚本的主要任务是检查安装环境是否符合要求并给出相应的提示,启动主安装程序(setup.exe)或执行安装任务(复制文件,访问注册表写入相关信息等),当setup.exe返回时报告安装结果。如下所示:
<BODY BACKGROUND="WinBack.gif">
<!-- 播放声音文件,窗口布局,如显示左上角图形、左下角广告、右下角“关闭”链接等,略... -->
<!-- 以下为主显示区域 -->
<DIV ID="mainClientArea" STYLE="position: absolute; top: 30px; left: 170px; width: 400px; FONT-SIZE: 10pt;">欢迎使用
<P>
<B>系统检查:</B>
<DIV ID="msAccessDetect" STYLE="position: relative; top: 15px" ></DIV>
<HR STYLE="position: absolute; top: 150; left: 0px;" />
<DIV ID="Install" STYLE="position: absolute; top: 160px; left: 0px;" >
已检查所有的安装条件 <BR/>
<BUTTON ID="cmdInstall" STYLE="position: relative; top: 20; left: 140px">开始安装</BUTTON>
</DIV>
</P>
</DIV>
<SCRIPT LANGUAGE="VBScript">
' 下面的代码在启动时运行
Call Main
Sub Main
Dim wscript
Const HEIGHT = 600
Const WIDTH = 400
' 调整窗口大小和位置
window.resizeTo HEIGHT, WIDTH
window.moveTo (screen.width - HEIGHT) / 2, (screen.height - WIDTH) / 2
' 检查Access是否已经安装,略...
End Sub
Function CheckInstallResult (lngReturnValue)
' 根据指定的返回值确定要返回的文字信息
select case lngReturnValue
case 0:
CheckInstallResult = "安装成功。"
' 其他检查条件 ...
case else
CheckInstallResult = "安装程序返回错误代码" & lngReturnValue & ". "
end select
End Function
</SCRIPT>
<SCRIPT FOR="cmdInstall" EVENT="onclick" LANGUAGE="VBScript">
Dim objShell
Dim lngReturn
on error resume next
set objShell = CreateObject( "WScript.Shell" )
' 调用主安装程序
lngReturn = objShell.Run ("setup.exe", 4, 1)
if Err.number <> 0 then
Install.innerText = "错误: " & Err.Description & Err.number
else
Install.innerText = CheckInstallResult(lngReturn)
end if
set objShell = Nothing
</SCRIPT>
</BODY>本回答被提问者和网友采纳
windows打开程序过程
参考技术A 当双击某个图标时,Explorer.exe进程的一个线程会侦测到这个操作,它根据注册表中的信息取得文件名,然后Explorer.exe 以这个文件名调用 CreateProcess 函数。注册表中有相关的项保存着双击操作的信息,如 exe 文件关联、启动 exe 的 Shell 是哪个。PC中的大多其它的进程都是 Explorer.exe 的子进程,因为它们都是由Explorer.exe 进程创建的。CreateProcess 实际上是通过 NtCreateProcess 函数实现的, 此时,系统会创建一个进程内核对象。进程内核对象可以看作是操作系统用来管理进程的小的数据结构,它是在内核堆区分配的一个结构体,是系统用来存放关于进程统计信息的地方。进程内核对象维护了一个句柄表的结构,当进程被初始化之后,其句柄表是空的。当进程内的一个线程通过指定的函数创建了一个内核对象时,内核会为对象分配一块内存区域并初始化这块区域,然后内核会在进程的句柄表中查找一个空的入口,找到之后会初始化句柄表的以索引定位的区域。初始化的主要过程就是填充句柄表的一个单元,包括指定内核对象地址,指定访问码,指定标记等。
进程内核对象创建后,它的引用计数被置为1。然后系统为刚刚创建的进程分配的进程虚拟地址空间。要注意了,之所以称为虚拟地址空间,就是因为这块地址空间并不在内存之中,它只是在硬盘上划分的被称为“页”的文件。每个进程都有自己的虚拟地址空间,在进程初始化的时候,其所有的程序和数据会被加载到这个地址空间中。等到真正运行的时候,系统为每个进程配置的页表会把虚拟地址映射为真正的物理地址(这个过程,我会在后面的博客中详细介绍如何映射)。
初始化虚拟地址空间。进程地址空间创建后,Windows的装载器(loader,也称为PE装载器)开始工作,Loader会读取EXE文件的信息(PE文件)。此时 loader 会检查PE文件的有效性,如果PE文件有错误,进程也就无法启动了。如果PE文件没有错误,装载器就把PE文件的内容(二进制代码)映射到进程的地址空间中,然后读取 PE文件的导入地址表(Import Table),这里存放有exe文件需要导入的模块文件(DLL),系统会一一加载这些DLL到进程的地址空间中,具体做法是调用 LoadLibrary 函数加载程序代码到某个地址,然后系统会映射这些代码到进程的地址空间中,要知道DLL只需加载一次就可映射到所有进程的地址空间(映射过程我会在后面详细阐述)中,并为每个DLL维护一个引用计数,当引用计数为 0 时,DLL就从内存中卸载,释放占用的内存。DLL里面可能又引用了其它的DLL,因此加载DLL时是递归形式的,直到加载完Import Table 里描述的所有DLL模块,此时进程初始化部分完成。
创建进程的主线程。当进程的初始化完成后,开始创建进程的主线程,一个进程至少要有一个主线程才能运行,可以说进程只是充当一个容器的作用,而线程才是执行代码的载体。线程是用 CreateThread 这个函数创建的。创建线程时,也和进程相似,系统会创建线程内核对象,初始化线程堆栈。线程堆栈有两个,一个是核心堆栈,由核心态维护;另一个是用户堆栈,运行在用户态下。同样的,线程的引用计数也置为1。
C/C++运行期库初始化。当进程的主线程初始化完成后,并且线程得到了CPU时间片,CPU把CS:IP指向程序入口(OEP),这个地址相当重要,因为这是程序运行时第一条指令所在的地址(我们可以使用一些PE辅助工具来查看PE文件的地址信息,注意真实地址==偏移地址 + 基址)。其实,CS:IP指向的地址处是一条JMP指令,它跳转到程序真正的入口函数,入口函数有以下4种形式:
···
mainCRTStartup (用于 ANSI 版本的控制台应用程序 )
wmainCRTStartup ( 用于 Unicode 版本的控制台应用程序 )
WinMainCRTStartup ( 用于 ANSI 版本的窗口应用程序 )
wWinMainCRTStartup ( 用于 Unicode 版本的窗口应用程序)
···
下面再看看入口函数的源码:
···
int XXXCRTStartup(void) //XXX表示不同Windows版本
__security_init_cookie(); // 完成安全方面的初始化
return__tmainCRTStartup();
···
在__tmainCRTStartup中首先调用了GetStartupInfoW函数取得父进程创建本进程时的启动信息, 然后又是一系列的初始化,其中包括C++构造函数的调用,还有静态变量,全局变量的初始化,这些操作是在_initterm这个函数中完成的。接着,我们的 (w)WinMain / (w)main 函数会被调用,到这时,用户程序代码才开始被执行。
以上是关于怎么在html中运行exe程序的主要内容,如果未能解决你的问题,请参考以下文章