1

我在 C# 中编写了一个自定义操作来检查驱动器是否存在,如下所示,我被困在两者之间。

 [CustomAction]
    public static ActionResult MySimpleAction(Session session)
    {        
        if (Directory.Exists("F:\\"))
        {
            return ActionResult.Success;
        }
        else
        {
            return ActionResult.Failure;
        }
    }

在 wxs 文件中,我正在运行自定义操作,如下所示。

 <Binary Id="myAction" SourceFile="MyCustomAction.CA.dll" />
 <CustomAction Id="myActionId"
                  BinaryKey="myAction"
                  DllEntry="MySimpleAction"
                  Execute="immediate"
                  Return="check" />

<InstallExecuteSequence>
  <Custom Action="myActionId" After="InstallInitialize"  >  </Custom> 
</InstallExecuteSequence>

如果我在有 F:\ 驱动器的目标机器上运行 msi,则安装成功,如果目标机器没有 F:\ 驱动器,则安装失败,我收到错误,因为“安装向导因错误而提前结束.你的系统没有被修改过。

我在这里要做的是,如果 F:\ 驱动器在目标计算机中可用(我的自定义操作成功),我想将我的根驱动器设置为 F:\,并且我想将应用程序安装在 F:\我的应用程序\Bin

     <Property Id="ROOTDRIVE"><![CDATA[F:\]]></Property>
     <Directory Id="TARGETDIR" Name="SourceDir">
       <Directory Id="INSTALLFOLDERLOCATION" Name="MyApp">
        <Directory Id="INSTALLLOCATION" Name="Bin">

如果 F:\ 驱动器在目标计算机中不可用(我的自定义操作失败),我想将我的根驱动器设置为 C:\,并且我想安装在 C:\MyApp\Bin

     <Property Id="ROOTDRIVE"><![CDATA[C:\]]></Property>
      <Directory Id="TARGETDIR" Name="SourceDir">
       <Directory Id="INSTALLFOLDERLOCATION" Name="MyApp">
        <Directory Id="INSTALLLOCATION" Name="Bin">

如何使用此自定义操作设置根驱动器属性?谢谢您的帮助!

4

3 回答 3

2

使用即时自定义操作时,您可以设置属性值,session["PROPERTYNAME"]以便在您的情况下可以session["ROOTDRIVE"] = "F:\\";在自定义操作中使用。

目前失败的原因是您从自定义操作中返回了失败消息,并且由于您指定Return="check"了 ,安装程序会检查返回值,如果自定义操作失败,则安装失败。

于 2013-01-24T11:36:23.370 回答
0

我感谢Christopher PainterChrisPatrick帮助我!!!下面的代码使技巧起作用。

 [CustomAction]
    public static ActionResult MySimpleAction(Session session)
    {
        session.Log("DriveInfo Starts");
        DriveInfo[] drives = DriveInfo.GetDrives();
        foreach (DriveInfo d in drives)
        {
            if (d.Name.Contains("F") & d.IsReady == true & d.DriveType.ToString() == "Fixed")
            {                   
              session["TARGETDIR"] = "F:\\";                   
            }
            else
            {
                session["TARGETDIR"] = "C:\\";
                session.Log("No F:\\ Drive Found!!!!");                    
            }
        }
        session.Log("DriveInfo Ends");
        return ActionResult.Success;

在 .wxs 文件中,

  <Binary Id="myAction" SourceFile="MyCustomAction.CA.dll" />

   <Directory Id="TARGETDIR" Name="SourceDir">
   <Directory Id="INSTALLFOLDERLOCATION" Name="MyApp">
    <Directory Id="INSTALLLOCATION" Name="Bin">

     <CustomAction Id="myActionId" BinaryKey="myAction" DllEntry="MySimpleAction" Execute="immediate" Return="check" />

      <InstallUISequence>
      <Custom Action="myActionId" Before="CostFinalize" > NOT Installed </Custom>      
      </InstallUISequence>
于 2013-01-30T13:08:27.480 回答
0

你在正确的轨道上。这是我做的不同的事情。

1)我使用 DriveInfo 类来查看驱动器是否存在并且它的 DriveType Fixed。(不是 CDROM、USB 驱动器、网络……)

2) 自定义操作在 AppSearch 之后的 UI 和 Execute 序列中安排,并设置一个名为 InstallDirOverride 之类的属性。自定义操作始终返回 ActionResult.Success。

3)我使用 Set Property 自定义操作(wxs 元素)将 InstallDirOverride 分配给 INSTALLLOCATION (或 INSTALLDIR ... 无论您调用主目录),条件是 INSTALLLOCATION 还没有值,而 InstallDirOverride 确实有值和未安装。此自定义操作在 CostInitialize 之前在 UI 序列和 ExecuteSequence 中安排。

所有这一切的结果是一个默认为 C:\Program Files\My Company\My Product 的安装程序,但根据您的 C# 自定义操作中的业务规则将其行为更改为默认为其他内容。这使您可以灵活地为特定平台环境默认您想要的方式,但在您的平台缺少该资源时仍然可以向 Windows 标准投诉。

于 2013-01-25T01:34:30.367 回答