Specify different path for provider iisApp when creating package with msdeploy

knut picture knut · Jul 7, 2011 · Viewed 10.5k times · Source

How I make the package

I make the msdeploy package like this:

msdeploy.exe -verb:sync -source:iisApp=c:\content\ -dest:package=c:\pkg.zip

The c:\content directory has a single index.html file.

Result

The output looks like this:

Info: Adding package (package).
Info: Adding child iisApp (c:\content\).
Info: Adding child createApp (c:\content\).
Info: Adding child contentPath (c:\content\).
Info: Adding child dirPath (c:\content\).
Info: Adding child filePath (c:\content\index.html).
Total changes: 6 (6 added, 0 deleted, 0 updated, 0 parameters changed, 0 bytes copied)

If I extract the content of c:\pkg.zip into directory c:\pkg it looks like this:

archive.xml
systemInfo.xml
Content\c_C
Content\c_C\content
Content\c_C\content\index.html

If I dump the package like this:

msdeploy.exe -verb:dump -source:package=c:\pkg.zip -xml

I get:

<output>
    <MSDeploy.iisApp>
        <iisApp path="c:\content\">
            <createApp 
                path="c:\content\" 
                isDest="False" 
                managedRuntimeVersion="" 
                enable32BitAppOnWin64="" 
                managedPipelineMode="" 
                applicationPool="" 
                appExists="True" />
            <contentPath path="c:\content\">
                <dirPath 
                    path="c:\content\" 
                    securityDescriptor="D:" 
                    parentSecurityDescriptors="" 
                    attributes="Directory">
                    <filePath 
                        path="index.html" 
                        size="0" 
                        attributes="Archive" 
                        lastWriteTime="07/07/2011 20:58:00" 
                        securityDescriptor="D:" />
                </dirPath>
            </contentPath>
        </iisApp>
    </MSDeploy.iisApp>
</output>

How I want it to be

I don't want the package to depend upon the current location of the site files. I'm going to send the package to a customer, and I don't want any detailes about the packaging process to get shipped with the package. I want the content of the package c:\pkg.zip to be like this:

archive.xml
systemInfo.xml
Content\index.html

I want the package to be able to create an IIS application, so I need a virtual path. I also want to install the package into the default location. So the physical path also has to change. I want the dump to look something like this:

<output>
    <MSDeploy.iisApp>
        <iisApp path="Default Web Site\Site">
            <createApp 
                path="Default Web Site\Site"
                isDest="False" 
                managedRuntimeVersion="" 
                enable32BitAppOnWin64="" 
                managedPipelineMode="" 
                applicationPool="" 
                appExists="False" />
            <contentPath path="c:\inetpub\wwwroot\site">
                <dirPath 
                    path="c:\inetpub\wwwroot\site" 
                    securityDescriptor="D:" 
                    parentSecurityDescriptors="" 
                    attributes="Directory">
                    <filePath 
                        path="index.html" 
                        size="0" 
                        attributes="Archive" 
                        lastWriteTime="07/07/2011 20:58:00" 
                        securityDescriptor="D:" />
                </dirPath>
            </contentPath>
        </iisApp>
    </MSDeploy.iisApp>
</output>

I have changed the iisApp and createApp provider path attributes to be Default Web Site\Site. And I changed the contentPath and dirPath provider path attributes to be c:\inetpub\wwwroot\site.


Questions

  • How can I accomplish this?

Answer

peter_raven picture peter_raven · Aug 5, 2011

You need to look at MS Deploy replace rules, a useful feature well hidden on the MS Deploy Team Blog.

In your case, you will need to extend your command line with a pile of replace expressions, something like this:

msdeploy.exe 
-verb:sync 
-source:iisApp=c:\content\ 
-dest:package=c:\pkg.zip
-replace:objectName=iisApp,targetAttributeName=path,
         replace="Default Website\Site"
-replace:objectName=createApp,targetAttributeName=path,
         replace="Default Website\Site"
-replace:objectName=contentPath,targetAttributeName=path,
         replace="c:\inetpub\wwwroot\site"
-replace:objectName=dirPath,targetAttributeName=path,match="^c:\content",
         replace="c:\inetpub\wwwroot\site"

Running this should produce your desired output.

In the above sample, the first 3 replace rules match by tag name (objectName) and attribute name (targetAttributeName), and overwrites with the specified replace string. The last replace rule will match all path attributes of all dirPath tags beginning with "c:\content" and will replace only that part of the attribute value with the replace string.

Finally, I haven't found a way to avoid having the package zip-file contain the original source folder names. The only workaround would be to package from a neutral, temporary location like "c:\site".

So the procedure is:

  • Copy your stuff to a neutral, temporary location.
  • Create your package from here.
  • Use the verb:dump to see the generated xml.
  • Create your package again with added replace rules for everything you want changed in the package.
  • Take a headache pill ;-)