【问题标题】:Adding application launch option (checkbox) to installations将应用程序启动选项(复选框)添加到安装
【发布时间】:2012-04-06 20:35:46
【问题描述】:

我在 .Net 中开发了我的应用程序,我的安装程序运行良好。

现在我想要更多功能,例如在安装程序末尾添加复选框,以便在单击完成按钮后启动相同的应用程序。

我也实现了这里给出的步骤:How can I customize an MSI in the Visual Studio setup/deployment project? 但最后无法得到复选框。

现有的 JScript 是这样的:

   // EnableLaaunchApplication.js <msi-file>
   // Performs a post-build fixup of an msi to launch a specific file when the install has completed


   // Configurable values
   var checkboxChecked = true;          // Is the checkbox on the finished dialog checked by default?
   var checkboxText = "Launch [ProductName]";   // Text for the checkbox on the  finished dialog
   var filename = "FlashApp.exe";   // The name of the executable to launch - change this to match the file you want to launch at the end of your setup


   // Constant values from Windows Installer
   var msiOpenDatabaseModeTransact = 1;

   var msiViewModifyInsert         = 1
   var msiViewModifyUpdate         = 2
   var msiViewModifyAssign         = 3
   var msiViewModifyReplace        = 4
   var msiViewModifyDelete         = 6



   if (WScript.Arguments.Length != 1)
   {
    WScript.StdErr.WriteLine(WScript.ScriptName + " file");
        WScript.Quit(1);
   }

   var filespec = WScript.Arguments(0);
   var installer = WScript.CreateObject("WindowsInstaller.Installer");
   var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);

   var sql
   var view
   var record

   try
   {
var fileId = FindFileIdentifier(database, filename);
if (!fileId)
    throw "Unable to find '" + filename + "' in File table";


WScript.Echo("Updating the Control table...");
// Modify the Control_Next of BannerBmp control to point to the new CheckBox
sql = "SELECT `Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Property`, `Text`, `Control_Next`, `Help` FROM `Control` WHERE `Dialog_`='FinishedForm' AND `Control`='BannerBmp'";
view = database.OpenView(sql);
view.Execute();
record = view.Fetch();
record.StringData(15) = "CheckboxLaunch";
view.Modify(msiViewModifyReplace, record);
view.Close();

// Resize the BodyText and BodyTextRemove controls to be reasonable
sql = "SELECT `Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Property`, `Text`, `Control_Next`, `Help` FROM `Control` WHERE `Dialog_`='FinishedForm' AND `Control`='BodyTextRemove'";
view = database.OpenView(sql);
view.Execute();
record = view.Fetch();
record.IntegerData(7) = 33;
view.Modify(msiViewModifyReplace, record);
view.Close();

sql = "SELECT `Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Property`, `Text`, `Control_Next`, `Help` FROM `Control` WHERE `Dialog_`='FinishedForm' AND `Control`='BodyText'";
view = database.OpenView(sql);
view.Execute();
record = view.Fetch();
record.IntegerData(7) = 33;
view.Modify(msiViewModifyReplace, record);
view.Close();

// Insert the new CheckBox control
sql = "INSERT INTO `Control` (`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Property`, `Text`, `Control_Next`, `Help`) VALUES ('FinishedForm', 'CheckboxLaunch', 'CheckBox', '18', '117', '343', '12', '3', 'LAUNCHAPP', '{\\VSI_MS_Sans_Serif13.0_0_0}" + checkboxText + "', 'CloseButton', '|')";
view = database.OpenView(sql);
view.Execute();
view.Close();



WScript.Echo("Updating the ControlEvent table...");
// Modify the Order of the EndDialog event of the FinishedForm to 1
sql = "SELECT `Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering` FROM `ControlEvent` WHERE `Dialog_`='FinishedForm' AND `Event`='EndDialog'";
view = database.OpenView(sql);
view.Execute();
record = view.Fetch();
record.IntegerData(6) = 1;
view.Modify(msiViewModifyReplace, record);
view.Close();

// Insert the Event to launch the application
sql = "INSERT INTO `ControlEvent` (`Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering`) VALUES ('FinishedForm', 'CloseButton', 'DoAction', 'VSDCA_Launch', 'LAUNCHAPP=1', '0')";
view = database.OpenView(sql);
view.Execute();
view.Close();



WScript.Echo("Updating the CustomAction table...");
// Insert the custom action to launch the application when finished
sql = "INSERT INTO `CustomAction` (`Action`, `Type`, `Source`, `Target`) VALUES ('VSDCA_Launch', '210', '" + fileId + "', '')";
view = database.OpenView(sql);
view.Execute();
view.Close();



if (checkboxChecked)
{
    WScript.Echo("Updating the Property table...");
    // Set the default value of the CheckBox
    sql = "INSERT INTO `Property` (`Property`, `Value`) VALUES ('LAUNCHAPP', '1')";
    view = database.OpenView(sql);
    view.Execute();
    view.Close();
}



database.Commit();
    }
    catch(e)
    {
WScript.StdErr.WriteLine(e);
WScript.Quit(1);
    }



    function FindFileIdentifier(database, fileName)
    {
var sql
var view
var record

// First, try to find the exact file name
sql = "SELECT `File` FROM `File` WHERE `FileName`='" + fileName + "'";
view = database.OpenView(sql);
view.Execute();
record = view.Fetch();
if (record)
{
    var value = record.StringData(1);
    view.Close();
    return value;
}
view.Close();

// The file may be in SFN|LFN format.  Look for a filename in this case next
sql = "SELECT `File`, `FileName` FROM `File`";
view = database.OpenView(sql);
view.Execute();
record = view.Fetch();
while (record)
{
    if (StringEndsWith(record.StringData(2), "|" + fileName))
    {
        var value = record.StringData(1);
        view.Close();
        return value;
    }

    record = view.Fetch();
}
view.Close();

    }

    function StringEndsWith(str, value)
    {
if (str.length < value.length)
    return false;

return (str.indexOf(value, str.length - value.length) != -1);
    }

【问题讨论】:

  • 但这对我不起作用...我在我的问题中指定了这一点
  • 你指的是哪里?为什么这对您没有帮助?
  • 我遵循了所有步骤并且还能够构建应用程序。现在我在输出日志中得到了类似的内容:E:\MYProject\EnableLaunchApplication.js(30, 1) Microsoft JScript 运行时错误:下标超出范围
  • 我更新了我的问题@DorCohen

标签: c# windows-installer setup-deployment


【解决方案1】:

您应该知道,Visual Studio 安装项目在很多方面都很糟糕。事实上,微软已将它们从 Visual Studio 11 中删除,并鼓励用户使用名为 Limited Edition 的免费版 InstallShield。 ISLE 支持在完成对话框中添加一个复选框来启动您的应用程序。另一种可能性是转换为 Windows Installer XML。这完全取决于您的需求以及您想投入多少时间来学习安装程序。

Visual Studio 安装项目隐藏了太多的底层 MSI,因此它非常有限。有一些方法可以通过对 MSI 的构建后 SQL 更新来破解它,但它确实是个麻烦事,而且不是一个可扩展的解决方案。

在我看来,这种脚本是毫无价值的。让我们打个比方。如果您正在使用 .NET 语言的某些实现(我们称之为 Bb)并且您发现它缺少一堆 CLR / .NET 功能,您会使用 postbuild 来操作生成的程序集中的 IL 吗?只是切换到更好的 CLR 语言,如 C#?这是同一件事。不要操纵生成的 MSI,切换到更好的工具。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-14
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    • 2011-01-23
    相关资源
    最近更新 更多