Create IIS Website without child WebApp

Mar 21, 2016 at 10:00 AM
I am making an Installer that Installs a few IIS websites.

What I see created is a WebSite with a WebApp inside it, that both point to the same physical path.
Image

How can I not install the child WebApp (MyWebApp in the screenshot)?

Thanks a bunch!
Mar 21, 2016 at 12:16 PM
It looks like it is a simple matter of passing a proper web site description (not a name) as a argument in the WebSite constructor. The samples reference the "DefaultWebSite". You may want to provide your own. The example below created new web site "Custom Web Site"
new IISVirtualDir
{
    Name = "MyWebApp",
    AppName = "Test",
    WebSite = new WebSite("CustomWebSite", "*:80", "Custom Web Site")
    {
        ...
Mar 21, 2016 at 12:42 PM
Edited Mar 21, 2016 at 12:46 PM
Thanks, I will try that.
Mar 21, 2016 at 1:47 PM
Edited Mar 21, 2016 at 3:10 PM
I am afraid this doesn't work.

To get the result I'm looking for you'll need not to create the WebVirtualDir element.

I think the correct solution is to inverse the order in which things refer to each other, A.k.a.
File.IISWebSites = {...
    VirtualDirs= {...}
}
That is also the hierarchy in IIS, so this seems logical. It will be a breaking change though.

EDIT: A problem I though about in the above solution, is that the virtualDir Directory is inferred from said file, which would be problematic if VirtualDir doesn't have direct connection to file.
So we'll need some re-design of the whole thing.
Another option is just to add a "Don't create" property in VirtualDir, which would be easy to implement and use, but a bit weird.
Mar 22, 2016 at 2:17 AM
Yeah, I also saw the problem. There is definitely a design limitation that makes VirtDir-WebSite relationship look like 1-to-1 while it is in fact N-to-1. And yes I had to resist my immediate temptation to solve it as WebSite.VirtuualDirs. Asking the user to explicitly link the file/dir isn't really an attractive option. I would really like to preserve auto-linking via inference.

After some experimenting with syntax I think I found an adequate compromise.

The existing implementation follows a typical 'foreign key' DB paradigm, which is fully compatible with N-to-1 model. The only aesthetical problem is that it is a bit unusual for OO. However it is exactly what we need if we are to keep inference. Thus the following solution already works:
var myWebSite = new WebSite("My Web Site", "*:80")
{
    InstallWebSite = true
};

var project =
        new Project("My Product",
            new Dir(@"%ProgramFiles%\MyCompany",
                new Dir(@"MyWebApp",
                    new File(@"MyWebApp\Default.aspx",
                        new IISVirtualDir
                        {
                            Name = "MyWebApp",
                            AppName = "Test",
                            WebSite = myWebSite 
                        }, 
                        new IISVirtualDir
                        {
                            Name = "MyWebApp1",
                            AppName = "Test1",
                            WebSite = myWebSite
                        }),
Correction: the current release works with a tiny adjustment as below. :)
project.WixSourceGenerated += doc =>
     doc.FindAll("WebSite")
        .Skip(1)
        .ForEach(x=>x.Remove();

And I will need to embed this correction into the engine for the next release.

If it's usable enough it may stay. If not WebSite.VirtuualDirs may be considered. But first I just want to provide a working solution for a problem, which is rather critical. Will keep you posted.

P.S. Your post also triggeres some rework with WebSite constructors. https://wixsharp.codeplex.com/workitem/102
Jun 8, 2016 at 11:22 PM
I was also looking for that feature: install a website without virtual directory.
The last Oleg's answer helped a lot.
Since I have only one website and would like to remove all virtual dirs the following code snippet works just fine:
            project.WixSourceGenerated += doc =>
                doc.FindAll("WebVirtualDir")
                    .ForEach(x => x.Remove());