MSDeploy runCommand using relative path

2019-02-06 02:49发布

问题:

I am trying to run a command as a part of my packaging/deployment process via MSDeploy. In particular, I am trying to create a custom event log by running installutil against one of my DLLs, but I am having trouble with specifying a relative path to the DLL from the deployment directory. To get started, I added the below config to my csproj in order to generate the runCommand provider inside of my Manifest file. Please note the absolute path to the DLL.

<PropertyGroup>
    <!-- Extends the AfterAddIisSettingAndFileContentsToSourceManifest action to create Custom Event Log -->
    <IncludeEventLogCreation>TRUE</IncludeEventLogCreation>
    <AfterAddIisSettingAndFileContentsToSourceManifest Condition="'$(AfterAddIisSettingAndFileContentsToSourceManifest)'==''">
      $(AfterAddIisSettingAndFileContentsToSourceManifest);
      CreateEventLog;
    </AfterAddIisSettingAndFileContentsToSourceManifest>
  </PropertyGroup>
  <Target Name="CreateEventLog" Condition="'$(IncludeEventLogCreation)'=='TRUE'">
    <Message Text="Creating Event Log" />
    <ItemGroup>
      <MsDeploySourceManifest Include="runCommand">
        <path>installutil C:\inetpub\wwwroot\MyTestApp\bin\BusinessLayer.dll</path>
      </MsDeploySourceManifest>
    </ItemGroup>
  </Target>
  <ItemGroup>

After calling msbuild, this generated my manifest correctly inside of my package.zip. When I ran MyTestApp.deploy.cmd /Y it correctly called msdeploy and deployed my files to inetpub\wwwroot\MyTestApp and ran my command from the manifest below:

<runCommand path="installutil C:\inetpub\wwwroot\MyTestApp\bin\BusinessLayer.dll ... etc 

The problem I am having is I do not want to hardcode this DLL path to c:\inetpub\etc. How can I make the above call using the relative path from my deployment directory under Default Web Site? Ideally, I would like MSDeploy to take this path and pass it as a variable to the runCommand statement in order to find the DLL. Then I could write something like: <path>installutil $DeploymentDir\NewTestApp\bin\BusinessLayer.dll</path> without having to worry about hard-coding an absolute path in.

Is there any way to do this without using the absolute path to my DLL every time?

回答1:

I realize this isn't the answer you probably wanted to hear but this is how I got around it.

We created a powershell script on the destination server. So instead of running your command:

installutil C:\inetpub\wwwroot\MyTestApp\bin\BusinessLayer.dll ... etc

We would run:

c:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe d:\powershell\installSites.ps1 siteName <NUL

The "sitename" is being passed in as a param into the powershell script. Inside the script it knows on that destination server which files to install, any commands that need to run, app pools to recycle, etc.

Again, not as easy as finding a relative path, but it does the job.



回答2:

You can add definition of DeploymentDir to the .csproj with the action you wrote above:

<PropertyGroup>
<DeploymentDir Condition="'$(Configuration)'=='Release' AND '$(DeploymentDir)'==''">Release Deployment Dir</DeploymentDir>
<DeploymentDir Condition="'$(Configuration)'=='Debug' AND '$(DeploymentDir)'==''">Debug Deployment Dir</DeploymentDir>
<DeploymentDir Condition="'$(DeploymentDir)'==''">C:\inetpub\wwwroot</DeploymentDir>
<AplicationName Condition="'$(Configuration)'=='Release' AND '$(AplicationName)'==''">NewTestApp</AplicationName>
<AplicationName Condition="'$(Configuration)'=='Debug' AND '$(AplicationName)'==''">MyTestApp</AplicationName>
<ApplicationDeploymentDir Condition="'$(ApplicationDeploymentDir)'==''">$(DeploymentDir)\$(ApplicationName)\bin</ApplicationDeploymentDir>
</PropertyGroup>

Theese conditions will allow to change everything from command line to take full control over the build process in your build system or script.

MSBuild.exe yourproj.proj /p:Configuration=Release /p:DeploymentDir=D:\package /p:ApplivationName=BestAppForever

And inside of your task you can use it

<ItemGroup>
  <MsDeploySourceManifest Include="runCommand">
    <path>installutil $(ApplicationDeploymentDir)\BusinessLayer.dll</path>
  </MsDeploySourceManifest>
</ItemGroup>