本文介绍一个工具:Setup Factory。在7.0版本中,Setup Factory的默认从属资源中仅支持VB5.0及VB6.0,想要在生成的安装程序中自动完成.NET FRAMEWORK的安装,从网上查了一下,须要按以下步骤做几件事:
首先找到Setup Factory安装目录下的Dependencies目录,在目录中新建一个dotnet2_0.xml的文件。
然后,在Dependencies目录下新建子目录,取名dotnet2_0,将.NET FRAMEWORK安装程序dotnetfx.exe拷至该子目录下,dotnetfx.exe可在VS 2005的安装目录下的SDK//v2.0//BootStrapper//Packages//dotnetfx目录下找到。
完成之后打开Setup Factory,选择:资源---从属---添加,可以看到.NET FRAMEWORK 2.0了。
文件dotnet2_0.xml内容如下:
<DependencyTemplate>

<Dependency>

<Name>Microsoft.NETFramework2.0</Name>

<RuntimeTempFolder>dotnet2_0</RuntimeTempFolder>

<RevisionDate>Friday,March30,2007</RevisionDate>

<Description>安装Microsoft.NETFramework2.0应用程序所需的运行时文件。</Description>

<DetectScript>

functionisDotNet_Installed()

--author:zhengxinhewww.admans.net

--Outputtothelogthatthe.NETdetectionhasstarted.

SetupData.WriteToLogFile("Success/t.NET2.0Module:Detectionscriptstarted./r/n",true);

--Gettheoperatingsystemname.

--Checktoseeiftheregistrykeyexists

DotNet_Registry=Registry.DoesKeyExist(HKEY_LOCAL_MACHINE,"Software//Microsoft//.NETFramework");

if(DotNet_Registry==nil)then

--Theregistrykeydoesnotexist

--Runthe.NETInstallationscript

--Outputtothelogfilethat.NETcouldnotbefound,soitwillbeinstalled.

SetupData.WriteToLogFile("Info/t.NET2.0Module:Noversionof.NET2.0fileswasfound..NET2.0willbeinstalled./r/n",true);

returnfalse;

end

--Thekeydoesexist

--Getthe.NETinstalllocationfromtheregistry

DotNet_Install_Location=Registry.GetValue(HKEY_LOCAL_MACHINE,"Software//Microsoft//.NETFramework","InstallRoot",true);

--Lookforthefilemscorcfg.dll

Does_File_Exist=DotNet_Install_Location.."//v2.0.50727//aspnet_rc.dll";

if(notFile.DoesExist(Does_File_Exist))then

--Thefiledoesnotexist

--Runthe.NETInstallationscript

--Outputtothelogfilethat.NETcouldnotbefound,soitwillbeinstalled.

SetupData.WriteToLogFile("Info/t.NET2.0Module:Noversionof.NET2.0filewasfound..NET2.0willbeinstalled./r/n",true);

returnfalse;

end

--Thefiledoesexist

--Gettheversionofmscorcfg.dll

msc_ver=File.GetVersionInfo(Does_File_Exist);

if(notmsc_ver)then

SetupData.WriteToLogFile("Info/t.NET2.0Module:noversionwasfound..NET2.0willbeinstalled./r/n",true);

returnfalse;

end



--Comparethereturnedvalueagainsttheneededvalue

Compare=String.CompareFileVersions(msc_ver.FileVersion,"2.0.50727.42");

if(Compare==-1)then

--Outputtothelogfilethatalesserversionof.NETwasfoundonthesystem

SetupData.WriteToLogFile("Info/t.NET2.0Module:Alesserversionof.NET2.0("..msc_ver.FileVersion..")wasfoundontheuserssystem./r/n",true);

returnfalse;

else

--aversionlessthanversion2.0isinstalled

--Outputtothelogfilethatalesserversionof.NETwasfoundonthesystem

SetupData.WriteToLogFile("Info/t.NET2.0Module:Aneworthisversionof.NET2.0wasfoundontheuserssystem./r/n",true);

returntrue;

end

end

</DetectScript>

<DetectFunction>isDotNet_Installed</DetectFunction>

<InstallScript>

--用在安装操作中的变量:

localstrMessage=[[安装程序检测到你的系统没有安装Microsoft.NETFramework2.0或者版本过旧。请点击“确定”进行安装,点击“取消”中止安装。]];

localstrDialogTitle="必需的技术文件";

localbShowUserPrompt=true;--设置为true来询问用户是否安装模块

localbRunInstallFile=true;--设置默认选择(是否默认运行安装)

localstrRuntimeSupportFolder=SessionVar.Expand("%TempLaunchFolder%//dotnet2_0");

localstrFileToRun=strRuntimeSupportFolder.."//dotnetfx.exe";

-----------------------------------------------------------------------------------------

--安装已启动。

SetupData.WriteToLogFile("成功/tdotnet2_0模块:安装脚本已启动。/r/n",true);

--删除临时文件和运行时支持文件夹(同时进行错误检查)

localfunctionPerformCleanUp()

File.Delete(strFileToRun);

error=Application.GetLastError();

iferror~=0then

SetupData.WriteToLogFile("错误/tdotnet2_0模块:无法删除临时文件(".._tblErrorMessages[error]..")/r/n",true);

end

Folder.Delete(strRuntimeSupportFolder);

error=Application.GetLastError();

iferror~=0then

SetupData.WriteToLogFile("错误/tdotnet2_0模块:无法删除临时文件夹(".._tblErrorMessages[error]..")/r/n",true);

end

end

--是否显示对话框来询问用户是否安装模块。

if(bShowUserPrompt)then

localnDialogResult=Dialog.Message(strDialogTitle,strMessage,MB_OKCANCEL,MB_ICONEXCLAMATION);

if(nDialogResult==IDOK)then

--用户选择安装模块。

bRunInstallFile=true;

--用户要安装它

SetupData.WriteToLogFile("成功/tdotnet2_0模块:用户已确认,准备安装。/r/n",true);

else

--用户不安装模块。

bRunInstallFile=false;

--用户回答否

SetupData.WriteToLogFile("成功/tdotnet2_0模块:用户不安装模块。/r/n",true);

end

end

--检查用户是否要安装运行时。

if(bRunInstallFile)then

--开始!

SetupData.WriteToLogFile("成功/tdotnet2_0模块:正在运行dotnet2_0安装程序。/r/n",true);

--“/R:N”命令行参数告诉VB安装程序若需要的话不要显示重启屏幕。

--我们将检测整个安装进程返回代码,若需要的话,还设置内部_NeedsReboot变量。

--【注意】在静默方式下,你不能添加命令行参数“/Q”来运行安装

localnResult=File.Run(strFileToRun,"/R:N","",SW_SHOWNORMAL,true);

if(nResult==3010)then

--VB安装指明它需要重启才能完成

--设置SetupFactory的重启变量,以便在安装结束时重启

_NeedsReboot=true;

--需要重启

SetupData.WriteToLogFile("成功/tdotnet2_0模块:dotnet2_0安装程序已告知它需要重启。/r/n",true);

end

--删除运行时安装程序文件,并删除临时文件夹

PerformCleanUp();

--全部完成!

SetupData.WriteToLogFile("成功/tdotnet2_0模块:dotnet2_0运行时安装完毕。/r/n",true);

else

--用户不想安装运行时,那么删除运行时安装程序文件,

--并删除临时文件夹,然后退出安装程序。

PerformCleanUp();

--全部完成!

SetupData.WriteToLogFile("成功/tdotnet2_0模块:dotnet2_0运行时未安装。/r/n",true);

Application.Exit();

end

</InstallScript>

<SupportFiles>

<File>#SUFDIR#/Dependencies/dotnet2_0/dotnetfx.exe</File>

</SupportFiles>

</Dependency>

</DependencyTemplate>
==========================================================================
制作安装程序,无非是复制文件、注册控件、注册服务、修改设置项(注册表、配置文件)等等。通过一些专门的安装制作软件不难做出一个专业的安装程序。
.net下的WinForm程序,制作安装包需要做些什么呢?
典型情况下可能需要做如下事情:
1、判断客户机是否安装了.net framework
2、复制程序文件
3、将某些控件加入到全局应用程序缓存(GAC),比如第三方的控件或是自己定义的具有强名称的控件
4、安装时的默认设置项,比如程序的配置文件、或修改注册表等
5、创建快捷方式、软件的卸载
制作安装程序的工具比较多,常见的比如InstallShield、Wise Install、以及VS本身自带安装程序制作功能,前2个都是专业级的安装制作工具,所以安装文件也是巨大。这里我们推荐一款制作安装程序的软件Setup factory7.0,使用这个软件能够轻松的制作出一个专业的安装程序,它内置一种跟VBS类似的脚本语言,通过编写action脚本,能够实现比较强大的一些,比如从网上下载一些需要的安装文件。
对于Setup factory7.0的一般性使用这里就不详细介绍了,自己稍微摸索一下就知道了。我只介绍一下关于如何判断是否安装了.net framework及自动下载框架的安装文件并安装、如何修改注册表项、自定义安装界面等。
1、如何判断是否安装了.net framework
这里是判断注册表中是否存在框架的注册项。需要在Setup factory中的工程-操作的OnStartup事件中写如下代码:
--判断是否安装了.net框架
hasInstalled=Registry.DoesKeyExist(HKEY_LOCAL_MACHINE,"Software/Microsoft/.NETFramework");
ifhasInstalled==falsethen
result=Dialog.Message("安装提示","运行本软件需要安装.Net框架1.1版,是否从网络中下载并安装?",MB_YESNO,MB_ICONQUESTION,MB_DEFBUTTON1)
ifresult==IDYESthen
isExists=HTTP.TestConnection("http://www.zhangyongjun.com/fdown/uploadfile/dotnetfx.exe",90,80);
ifisExists==truethen
--ShowtheStatusDlg
StatusDlg.Show(MB_ICONINFORMATION,false);
StatusDlg.ShowCancelButton(true,"取消");

--Setstatusdlgtitleandmessage
StatusDlg.SetTitle("下载所需文件...");
--Setmeterrange(maxrange=65534)
StatusDlg.SetMeterRange(0,100);
--Downloadafilefromtheinternettotheuser'scomputer
--UsesDownloadCallback()asthecallbackfunction
HTTP.Download("http://www.zhangyongjun.com/fdown/uploadfile/dotnetfx.exe",SessionVar.Expand("%TempFolder%/dotnetfx.exe"),MODE_BINARY,20,80,nil,nil,DownloadCallback);

--HidetheStatusDlg
StatusDlg.Hide();
Shell.Execute(SessionVar.Expand("%TempFolder%/dotnetfx.exe"),"open","","",SW_SHOWNORMAL)
else
Dialog.Message("错误提示","下载文件失败,可能服务器已停止服务。请从Microsoft网站上下载.NetFramework1.1。",MB_ICONEXCLAMATION);
Application.Exit(0);
end
else
Application.Exit(0);
end
end

--CallbackfunctionforHTTP.Download
functionDownloadCallback(nDownloaded,nTotal,TransferRate,SecondLeft,SecondsLeftFormat,Message)
--Converttotalanddownloadedbytesintoformattedstrings
sDownloaded=String.GetFormattedSize(nDownloaded,FMTSIZE_AUTOMATIC,true);
sTotal=String.GetFormattedSize(nTotal,FMTSIZE_AUTOMATIC,true);
--Outputtimeleft,formatted.
StatusDlg.SetMessage("正在下载文件...剩余时间:"..SecondsLeftFormat);
--Outputformattedsizestouserthroughstatusdlgstatustext
StatusDlg.SetStatusText("已下载:"..sDownloaded.."/"..sTotal);
--Setmeterposition(fractiondownloaded*maxmeterrange)
StatusDlg.SetMeterPos((nDownloaded/nTotal)*100);
end

2、操作注册表
在定制安装界面中,可以添加一个界面,选择界面类型,并且能够自定义界面上的操作事件,比如在OnPreload、OnNext、OnBack、OnCancel、OnHelp编写脚本以实现特定的功能,下面的代码是实现在自定义的配置设置界面中用户填写完配置信息后,点“下一步”时,将填写的信息写入到注册表,其中CTRL_EDIT_01等为编辑控件(这里是文本框)的ID。
--这些操作在点击“下一步”按钮时执行。
--提示:你可以在这里添加验证用户输入信息的操作
Registry.CreateKey(HKEY_LOCAL_MACHINE,"Software/FengcheSoft/TradeSystem");
tEditFieldServer=DlgEditField.GetProperties(CTRL_EDIT_01);
tEditFieldDBUser=DlgEditField.GetProperties(CTRL_EDIT_02);
--Debug.ShowWindow(true);

Registry.SetValue(HKEY_LOCAL_MACHINE,"Software/FengcheSoft/TradeSystem","ServerName",tEditFieldServer.Text,REG_SZ);
Registry.SetValue(HKEY_LOCAL_MACHINE,"Software/FengcheSoft/TradeSystem","DBUser",DlgEditField.GetProperties(CTRL_EDIT_02).Text,REG_SZ);
Registry.SetValue(HKEY_LOCAL_MACHINE,"Software/FengcheSoft/TradeSystem","DBPwd",DlgEditField.GetProperties(CTRL_EDIT_03).Text,REG_SZ);
Registry.SetValue(HKEY_LOCAL_MACHINE,"Software/FengcheSoft/TradeSystem","DBName",DlgEditField.GetProperties(CTRL_EDIT_04).Text,REG_SZ);

Debug.Print(tEditFieldServer.Text);
test=Registry.GetValue(HKEY_LOCAL_MACHINE,"Software/FengcheSoft/TradeSystem","ServerName",true);
Debug.Print(test);
--进入下一个屏幕
Screen.Next();
