【问题标题】:Visual Studio Install Project: Get Target DirectoryVisual Studio 安装项目:获取目标目录
【发布时间】:2010-02-18 23:16:41
【问题描述】:

我一直在搜索 Google,试图找到合适的方法来确定用户从安装向导中选择的安装路径。

基本上我遇到了一个问题,我的服务无法在它自己的目录中创建文件,因为它缺乏适当的权限。我假设解决此问题的正确方法是确保服务使用的任何帐户都被授予对其文件夹的适当文件权限。

但在我解决如何通过 .Net 设置权限之前,我需要知道安装文件夹。我正在使用一个安装项目,它有一个 Installer 类,其中还包含一个 ServiceInstaller 控件。两者都具有Context 属性,因此我一直在检查每个安装程序的 AfterInstall 事件触发时可用的参数。起初我以为我会看到 TargetDir 属性集,但事实并非如此。但是,我看到 AssemblyPath 设置并指向相应文件夹的可执行文件。

基本上我只是想确保这是我应该使用的适当方法:

private void ProjectInstaller_AfterInstall(object sender, InstallEventArgs e)
{
    string InstallPath = System.IO.Path.GetDirectoryName(serviceInstaller1.Context.Parameters["AssemblyPath"]);;
}

【问题讨论】:

    标签: visual-studio-2008 windows-services installation


    【解决方案1】:

    我发现,Berg 提供的解决方案对我有用,除了将这个值用于 CustomActionData 属性:

    /TargetDir="[TARGETDIR]\"
    

    注意反斜杠的添加。看到这个article on MSDN

    【讨论】:

    • 您还必须在反斜杠“\”之后添加一个额外的空格。否则在安装或卸载时可能会出现 FileNotFoundException 异常。请参阅herehere
    • 你在哪里使用这段文字?你的解释对我来说不是很清楚,对不起。作为项目的命令行参数?代码中的某个地方?与 MSDN 的链接现在也已断开。感谢微软! :-)
    • 哦,我现在明白了。我在另一篇文章中找到了答案:“在您的部署项目中,为安装和提交添加自定义操作。对于安装自定义操作的 CustomActionData 属性,输入 /Targetdir="[TARGETDIR]\" "
    【解决方案2】:

    您的自定义操作是延迟的自定义操作,只有某些属性可供它使用,有关更多详细信息,请参阅以下页面,http://msdn.microsoft.com/en-us/library/aa370543(VS.85).aspx。您可以将 TARGETDIR 属性添加到 Visual Studio 2008 中的 CustomActionData;但是,我没有将 Visual Studio 2008 用作创作工具。

    在 Visual Studio 2008 中进行复杂的安装非常困难,因为它抽象出了 MSI 的许多关键功能。我强烈建议您看看 WiX。

    即使您不使用 WiX,您也需要下载 Orca,http://msdn.microsoft.com/en-us/library/aa370557(VS.85).aspx 并使用它来验证您的安装。这将为您节省无数小时。

    【讨论】:

    • WiX 可以安装 Windows 服务吗?
    • 是的,WiX 能够安装服务。您只需要编写 ServiceInstall 元素 wix.sourceforge.net/manual-wix2/wix_xsd_serviceinstall.htm。 WiX 和 Visual Studio 2008 安装项目都只是 MSI 的前端。如果您决定使用 WiX,我建议您阅读 msdn.microsoft.com/en-us/library/aa370566(VS.85).aspx 及其所有子条目。它将帮助您了解组件和功能。我最初开始使用 Visual Studio 2003\2005 进行安装,但遇到了太多限制。
    • 我不得不为这个项目坚持使用 Visual Studio 安装项目,但 +1 为我提供了未来研究的可行替代方案。 :)
    【解决方案3】:

    在安装过程中,我这样做了:

    // locate the installation directory and store it where we can find it during Commit
    stateSaver.Add("TargetDir", Context.Parameters["DP_TargetDir"]);
    

    然后,我可以稍后在OnCommitted 期间访问TargetDir

    string path = (string)savedState["TargetDir"];
    

    不确定这是否有帮助!我正在尝试弄清楚如何可靠地确定安装目录,以便我的服务可以进行一些日志记录。

    【讨论】:

      【解决方案4】:

      对于那些有多个的人将不得不这样做

      /AppID="[APPID]" /Path="[TARGETDIR]\"
      

      【讨论】:

        【解决方案5】:

        作为设置项目的替代方法,您可以使用一些安装程序构建服务。我认为,使用http://installer.codeeffects.com,您可以从您的网站加载任何文件,并在用户安装您的服务时将它们放在安装目录中。希望这会有所帮助。

        【讨论】:

          【解决方案6】:

          要在自定义操作中获取目标目录属性值,您可以通过在自定义操作视图中选择自定义操作输出并输入以下内容手动转发它:

          /TargetDir="[TARGETDIR]"
          

          作为 CustomActionData 属性的值。

          您应该可以通过以下方式访问它:

          string targetDir = Context.Parameters[ "TargetDir" ];
          

          【讨论】:

          • 正如我在问题中所说,我检查了该值,但不幸的是它在事件触发时未设置。
          【解决方案7】:

          据我所知,这是确定安装目录的唯一方法。当然,如果有人提出不同的答案,我会注意,但在此之前,这是我正在采取的方法。

          【讨论】:

          • 这不是答案。无论您使用哪种解决方案都是答案。