C# 通过Visual Studio安装程序的命令行发送自定义操作数据
我有一个Visual Studio安装程序,它有一个自定义UI,其中有一个文本框,用于恢复设置为C# 通过Visual Studio安装程序的命令行发送自定义操作数据,c#,visual-studio-2010,command-line,installation,custom-action,C#,Visual Studio 2010,Command Line,Installation,Custom Action,我有一个Visual Studio安装程序,它有一个自定义UI,其中有一个文本框,用于恢复设置为QUEUEDIRECTORY属性的值。然后我有一个自定义操作(一个安装程序类),它通过以下行传入该属性值/queuedir=“[QUEUEDIRECTORY]”-安装程序工作得很好 现在,我需要通过命令行发送该值,以便整个组织的系统管理员都可以运行此安装程序。因此,我尝试了以下命令行语句,但它就是不起作用 msiexec /i Setup.msi QUEUEDIRECTORY="D:\temp" Se
QUEUEDIRECTORY
属性的值。然后我有一个自定义操作(一个安装程序类),它通过以下行传入该属性值/queuedir=“[QUEUEDIRECTORY]”
-安装程序工作得很好
现在,我需要通过命令行发送该值,以便整个组织的系统管理员都可以运行此安装程序。因此,我尝试了以下命令行语句,但它就是不起作用
msiexec /i Setup.msi QUEUEDIRECTORY="D:\temp"
Setup.msi QUEUEDIRECTORY="D:\temp"
Setup.msi queuedir="D:\temp"
msiexec /i Setup.msi queuedir="D:\temp"
此外,我在网上似乎找不到任何让人感觉不到他们入侵的东西,因为他们就是找不到解决方案。我的意思是,我已经找到了一些解决方案,他们正在编辑MSI数据库和所有内容,但这似乎不是正确的解决方案,尤其是自从我使用Visual Studio 2010以来,Microsoft自首次发布此产品以来,确实做了一些增强
这是一个看起来会起作用,但仍然感觉像是一个黑客
无论如何,我希望你能帮助我 好的,所以我最终选择了我在问题中链接的解决方案。但是为了完整起见,让我把脚本放在这里。我需要做的第一件事是构建一个JS文件,该文件包含以下代码(我将其命名为
CommandLineSupport.JS
),并将其放在.vdproj
所在的目录中
//This script adds command-line support for MSI build with Visual Studio 2008.
var msiOpenDatabaseModeTransact = 1;
if (WScript.Arguments.Length != 1)
{
WScript.StdErr.WriteLine(WScript.ScriptName + " file");
WScript.Quit(1);
}
WScript.Echo(WScript.Arguments(0));
var filespec = WScript.Arguments(0);
var installer = WScript.CreateObject("WindowsInstaller.Installer");
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);
var sql
var view
try
{
//Update InstallUISequence to support command-line parameters in interactive mode.
sql = "UPDATE InstallUISequence SET Condition = 'QUEUEDIRECTORY=\"\"' WHERE Action = 'CustomTextA_SetProperty_EDIT1'";
view = database.OpenView(sql);
view.Execute();
view.Close();
//Update InstallExecuteSequence to support command line in passive or quiet mode.
sql = "UPDATE InstallExecuteSequence SET Condition = 'QUEUEDIRECTORY=\"\"' WHERE Action = 'CustomTextA_SetProperty_EDIT1'";
view = database.OpenView(sql);
view.Execute();
view.Close();
database.Commit();
}
catch(e)
{
WScript.StdErr.WriteLine(e);
WScript.Quit(1);
}
当然,您需要通过在Orca中打开MSI并将其与您创建的自定义对话框上的属性匹配来确保您正在替换正确的操作
接下来,既然JS文件正常工作了,我需要向.vdproj
添加一个PostBuildEvent
,您可以通过单击Visual Studio中的安装项目并点击F4来完成。然后找到PostBuildEvent
属性并单击省略号。在该PostBuildEvent
中放置此代码:
cscript "$(ProjectDir)CommandLineSupport.js" "$(BuildOutputPath)Setup.msi"
确保用msi文件名替换Setup.msi
虽然我仍然觉得这是一个黑客。。。因为它是。。。它起作用了,现在就可以了。这是一个足够小的项目,实际上没什么大不了的。这就是我在VisualStudio2010中将仅命令行属性值添加到MSI中所做的。这与公认的答案相似,但不太老套。在安装项目(.vdproj)目录中创建CommandLineSupport.js
,代码如下:
//This script adds command-line support for MSI installer
var msiOpenDatabaseModeTransact = 1;
if (WScript.Arguments.Length != 1)
{
WScript.StdErr.WriteLine(WScript.ScriptName + " file");
WScript.Quit(1);
}
WScript.Echo(WScript.Arguments(0));
var filespec = WScript.Arguments(0);
var installer = WScript.CreateObject("WindowsInstaller.Installer");
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);
var sql
var view
try
{
sql = "INSERT INTO `Property` (`Property`, `Value`) VALUES ('MYPROPERTY', 'MYPROPERTY=\"\"')";
view = database.OpenView(sql);
view.Execute();
view.Close();
database.Commit();
}
catch(e)
{
WScript.StdErr.WriteLine(e);
WScript.Quit(1);
}
然后在Visual Studio中单击部署项目以查看项目的属性,并将PostBuildEvent
设置为:
cscript.exe“$(ProjectDir)CommandLineSupport.js”“$(builtoputpath)”
然后使用自定义操作设置Delopyment项目。单击主输出以获取自定义操作属性,并将CustomActionData
字段设置为/MYPROPERTY=“[MYPROPERTY]”
然后,您可以在自定义操作安装程序类中访问该属性,如下所示:
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
string the_commandline_property_value = Context.Parameters["MYPROPERTY"].ToString();
}
INSERT INTO `Property` (`Property`, `Value`) VALUES ('MYPROPERTY', 'MYPROPERTY=\"\"'),('MYPROPERTY2', 'MYPROPERTY2=\"\"', ('MYPROPERTY3', 'MYPROPERTY3=\"\"')) ";
最后,您可以运行cmd<代码>C:\>Setup.msi MYPROPERTY=值
这不需要在Orca中进行任何处理,也不需要使用任何自定义对话框控件,如接受答案中的控件。您也不必修改PostBuildEvent来获得正确的.msi名称。等等。还可以添加任意数量的属性,如下所示:
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
string the_commandline_property_value = Context.Parameters["MYPROPERTY"].ToString();
}
INSERT INTO `Property` (`Property`, `Value`) VALUES ('MYPROPERTY', 'MYPROPERTY=\"\"'),('MYPROPERTY2', 'MYPROPERTY2=\"\"', ('MYPROPERTY3', 'MYPROPERTY3=\"\"')) ";
玩得开心 这是一个古老的线程,但有一个更简单、有效的解决方案似乎仍然很难找到,因此我在这里发布它
在我的场景中,我们正在使用VS2013(社区版)和扩展。我们的安装程序项目有一个收集两个用户文本的自定义UI步骤和一个绑定到接收这些文本的Install\Start步骤的自定义操作
我们可以通过GUI安装向导来完成这项工作,但不能通过命令行。最后,接下来,我们还能够使命令行工作,无需任何MSI文件或进行编辑
//This script adds command-line support for MSI build with Visual Studio 2008.
var msiOpenDatabaseModeTransact = 1;
if (WScript.Arguments.Length != 1)
{
WScript.StdErr.WriteLine(WScript.ScriptName + " file");
WScript.Quit(1);
}
WScript.Echo(WScript.Arguments(0));
var filespec = WScript.Arguments(0);
var installer = WScript.CreateObject("WindowsInstaller.Installer");
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);
var sql
var view
try
{
//Update InstallUISequence to support command-line parameters in interactive mode.
sql = "UPDATE InstallUISequence SET Condition = 'QUEUEDIRECTORY=\"\"' WHERE Action = 'CustomTextA_SetProperty_EDIT1'";
view = database.OpenView(sql);
view.Execute();
view.Close();
//Update InstallExecuteSequence to support command line in passive or quiet mode.
sql = "UPDATE InstallExecuteSequence SET Condition = 'QUEUEDIRECTORY=\"\"' WHERE Action = 'CustomTextA_SetProperty_EDIT1'";
view = database.OpenView(sql);
view.Execute();
view.Close();
database.Commit();
}
catch(e)
{
WScript.StdErr.WriteLine(e);
WScript.Quit(1);
}
其要点是直接从Visual Studio为所有需要的自定义对话框属性设置一个值,该值的格式应为[您的对话框属性名称]
。此外,似乎这些“公共”属性必须用大写字母命名
以下是最终设置:
自定义对话框属性
注释,例如Edit1属性和Edit1值
自定义操作属性
注意:代码后面使用的属性键可以用驼峰大小写命名
自定义操作代码
string companyId = Context.Parameters["companyId"];
string companyApiKey = Context.Parameters["companyApiKey"];
> setup.exe COMPANYID="Some ID" COMPANYAPIKEY="Some KEY" /q /l mylog.txt
命令行
string companyId = Context.Parameters["companyId"];
string companyApiKey = Context.Parameters["companyApiKey"];
> setup.exe COMPANYID="Some ID" COMPANYAPIKEY="Some KEY" /q /l mylog.txt
HTH与之相关的黑客攻击是真正解决这一问题的唯一方法。当用户界面中有文本框时,生成的Visual Studio MSI文件具有一个无条件自定义操作,该操作将属性设置为空白,因此当您在命令行上指定该属性时,它将被内部自定义操作破坏。