Visual Studio安装项目学习笔记(续)
这个月里对之前做的MSI安装包做了比较大的改动,主要是在安装的时候接受用户输入的域账号密码并进行检验,这使得本来几十行的PostBuild脚本暴增一百多行,后来有陆续做了很多细微修改,最终的脚本是350多行囧……主要修改如下(杂七杂八的UI修改就不列举了,都是些简单的SQL):- 在选择安装目录前增加一个对话框接受并检验用户输入的域账号
首先在Visual Studio安装项目的View→User Interface里增加一个TextBox(A),里面的Edit1、Edit2、Edit3分别用于输入域、用户名、密码,把Edit4隐掉。在脚本里给Edit3加上Password Mask:
sql = "SELECT `Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Property`, `Text`, `Control_Next`, `Help` FROM `Control` WHERE `Dialog_`='CustomTextA' AND `Control`='Edit3'";
view = database.OpenView(sql);
view.Execute();
record = view.Fetch();
record.IntegerData(8) = 1 + 2 + 4 + 2097152; // msidbControlAttributesVisible + msidbControlAttributesEnabled + msidbControlAttributesSunken + msidbControlAttributesPasswordInput
view.Modify(msiViewModifyReplace, record);
view.Close();
然后在MsiHiddenProperty属性里把EDITA_PASSWORD属性设为隐藏,防止在log里输出(会变成********):
sql = "INSERT INTO `Property` (`Property`, `Value`) VALUES ('MsiHiddenProperty', 'EDITA_PASSWORD')";
view = database.OpenView(sql);
view.Execute();
view.Close();
接着需要一个MSI Custom Action DLL来进行域账号的检验,用VC6建一个DLL项目,然后添加一个和项目同名的DEF文件:
LIBRARY "<DLL名>"
DESCRIPTION '描述'
EXPORTS
<函数名>
函数原型是UINT __stdcall <函数名>(MSIHANDLE hInstall)
不用DEF文件的话可以在主CPP开头添加
#pragma comment(linker, "/EXPORT:<函数名>=_<函数名>@4")
函数原型为
extern "C" __declspec(dllexport) UINT __stdcall <函数名>(MSIHANDLE hInstall)
麻烦的是在Custom DLL里不能调用MsiProcessMessage函数来弹出对话框,害我又在脚本里加了一百行左右的代码来增加一个自定义的错误消息对话框,需要修改Dialog、Control、ControlEvent和Property(这个不是必须)表
在Binary和CustomAction表插入生成的DLL(其中第二条SQL的“1”表示在Binary表的DLL,“Validate”是DLL函数名):
sql = "INSERT INTO `Binary` (`Name`, `Data`) VALUES (?, ?)";
record = installer.CreateRecord(2);
record.StringData(1) = "CheckDomainAccountDll";
record.SetStream(2, "./CheckDomainAccount.dll");
view = database.OpenView(sql);
view.Execute(record);
view.Close()
sql = "INSERT INTO `CustomAction` (`Action`, `Type`, `Source`, `Target`) VALUES ('CheckDomainAccount', '1', 'CheckDomainAccountDll', 'Validate')";
view = database.OpenView(sql);
view.Execute();
view.Close();
最后还要修改ControlEvent和Property(这个不是必须)表 - 使安装包安装的时候不覆盖并且卸载的时候不删除myprogramsetting.ini
sql = "SELECT `File`, `Component_`, `FileName`, `FileSize`, `Version`, `Language`, `Attributes`, `Sequence` FROM `File` WHERE `FileName`='MYPROG~1.INI|myprogramsetting.ini'";
view = database.OpenView(sql);
view.Execute();
record = view.Fetch();
stringvalue = record.StringData(2);
view.Close();
sql = "SELECT `Component`, `ComponentId`, `Directory_`, `Attributes`, `Condition`, `KeyPath` FROM `Component` WHERE `Component`='" + stringvalue + "'";
view = database.OpenView(sql);
view.Execute();
record = view.Fetch();
record.IntegerData(4) = 16 + 128; // msidbComponentAttributesPermanent + msidbComponentAttributesNeverOverwrite
view.Modify(msiViewModifyReplace, record);
view.Close(); - 卸载后提示用户重启
sql = "INSERT INTO `InstallExecuteSequence` (`Action`, `Condition`, `Sequence`) VALUES ('ScheduleReboot', 'REMOVE<>/"/"', '7000')";
view = database.OpenView(sql);
view.Execute();
view.Close(); - 在“添加删除程序”里不出现“修改”和“修复”按钮
sql = "INSERT INTO `Property` (`Property`, `Value`) VALUES ('ARPNOMODIFY', '1')"
view = database.OpenView(sql);
view.Execute();
view.Close();
sql = "INSERT INTO `Property` (`Property`, `Value`) VALUES ('ARPNOREPAIR', '1')"
view = database.OpenView(sql);
view.Execute();
view.Close();
顺便update以下前贴的两个遗留问题再新增一个:
● Log输出问题仍然没解决,不用Windows Installer 4.0(新增MsiLogging和MsiLogLocation属性)的话就要改BootStrapper,巨烦,方法和代码在这里
● 要在卸载最后显示一个对话框的话可以修改InstallExecuteSequence表实现,可能需要新增一个对话框(通过修改Dialog、Control、ControlEvent和Property表实现)
● 其实验证域账号的时候最好可以同时验证该账号在本机上的管理员权限,不过没什么时间和精力去研究,reference在下面,哪位同学研究过的给我讲解下吧てへっ~
REFERENCE:
microsoft.public.platformsdk.msi
http://groups.google.com/group/microsoft.public.platformsdk.msi
Create custom dialogs for use in your Visual Studio Setup projects
http://www.codeproject.com/KB/install/vsSetupCustomDialogs.aspx
Set a password textbox for Visual Studio .NET setup project
http://www.codeproject.com/KB/install/setupprjpwd.aspx
MSI Custom Action DLL
http://www.codeproject.com/KB/install/msicustomaction.aspx
Automation Interface Reference
http://msdn2.microsoft.com/en-us/library/aa367810%28VS.85%29.aspx
How to validate user credentials on Microsoft operating systems
http://support.microsoft.com/?id=180548
.NET Remoting Authentication and Authorization Sample - Part I
http://msdn2.microsoft.com/en-us/library/ms973911.aspx
Credential Management with the .NET Framework 2.0
http://msdn2.microsoft.com/en-us/library/aa480470.aspx
Using Credential Management in Windows XP and Windows Server 2003
http://msdn2.microsoft.com/en-us/library/aa302353.aspx
MAKEMSI
http://makemsi-manual.dennisbareis.com/
izfree Tools (C# wrapper for MSI SDK)
http://sourceforge.net/projects/izfree/
C# wrapper for Windows Installer
http://www.youseful.net/msi/MSIDLLDemo.zip
本文由VS软件圈(vssoft.net)发布,不代表VS软件圈立场,转载联系作者并注明出处:https://vssoft.net/vsazwt/VS2015anzhuangwenti/2020/0725/4555.html