【问题标题】:Using ServerManager to create Application within Application使用 ServerManager 在 Application 中创建 Application
【发布时间】:2010-12-23 11:06:04
【问题描述】:

我正在使用 ServerManager (Microsoft.Web.Administration.dll) 在 IIS 7 上的网站内创建应用程序。 我需要在此应用程序中创建应用程序或将虚拟目录转换为应用程序(如 iis 管理器功能右键单击 -> 转换为应用程序) 这怎么可能?我发现关于这个库的文档很少,而且没有一个提到这个特定的功能。 谢谢。

【问题讨论】:

    标签: c# iis configuration iis-7


    【解决方案1】:

    执行此操作的方法是操作Site.Applications 集合,该集合是您站点中所有应用程序的扁平树。

    为了这些示例,我们假设一个名为“MySite”的站点,其内容位于本地硬盘上:d:\mysite\www。该站点的 IIS 编号是 3,并且该站点驻留在自己的应用程序池中,也称为“MySite”。

    我们还将假设站点的文件夹结构如下

    首先,我们获取要添加应用程序的站点,我们将在整个过程中使用变量site

    // Get my site
    Site site = serverManager.Sites.First(s => s.Id == 3);
    

    根“/”应用程序:

    每个站点都有一个“根”应用程序。如果我们打开位于%systemroot%\windows\system32\inetsrv\config 中的applicationHost.config 并找到我们网站的<site> 节点,我们会看到以下内容:

    <site name="MySite" id="3">
      <application path="/" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="d:\mysite\www" />
      </application>
    </site>
    

    每个&lt;site&gt; 都包含&lt;application&gt; 的集合。总会有至少一个定义根应用程序的应用程序,/

    applicationPool 属性指定要使用的应用程序池。

    请注意,只有一个子元素:virtualDirectory

    每个application 都有一个virtualDirectory 元素的子集合,并且该集合中通常至少有一个元素。

    根应用程序中的默认&lt;virtualDirectory&gt; 告诉我们:

    • 这是根 (path="/") 和
    • 它物理上位于文件系统上d:\MySite\www (physicalPath="d:\MySite\www")。

    每个virtualDirectorypath 都与父application 路径中指定的path 相关。

    添加虚拟目录:

    如果我们想将虚拟目录添加到映射到文件系统上其他位置的“站点根目录”,我们会这样做:

    Application rootApp = site.Applications.First(a => a.Path == "/");
    rootApp.VirtualDirectories.Add("/vdir_1", @"D:\MySite\other_content");
    serverManager.CommitChanges();
    

    生成的配置如下所示:

    <site name="MySite" id="3">
      <application path="/" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="D:\MySite\www" />
        <virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
      </application>
    </site>
    

    我们在 IIS 管理器中看到了这一点:

    将虚拟目录添加到现有虚拟目录:

    如果我们想将子虚拟目录添加到 vdir1,我们会这样做:

    root.VirtualDirectories.Add("/vdir_1/sub_dir1", @"d:\MySite\more_content");
    

    这会导致:

    <site name="MySite" id="3">
      <application path="/" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="D:\MySite\www" />
        <virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
        <virtualDirectory path="/vdir_1/sub_dir1" physicalPath="D:\MySite\more_content" />
      </application>
    </site>
    

    IIS 管理器:

    添加虚拟目录时需要注意以下几点:

    • 如前所述,虚拟path 始终相对于父应用程序path
    • 虚拟path 的最后一部分,例如/vdir_1.../sub_dir1 成为虚拟目录的名称
    • 让多个虚拟目录指向同一个物理文件夹是完全合法的
    • 除了虚拟目录路径的名称部分之外,路径的所有部分应该作为物理路径或网站根目录中的虚拟路径存在 (d:\MySite\www)。即path 应该能够覆盖已经存在的内容,否则在 IIS 管理器中将看不到虚拟目录。

    关于最后一点,例如,我们没有名为 /vdir_2 的物理文件夹或虚拟目录,但以下代码是完全合法的:

    root.VirtualDirectories.Add("/vdir_2/sub_dir1", @"d:\MySite\even_more_content");
    

    您不会在 IIS 管理器中看到 /vdir_2/sub_dir1,但它是合法的,您实际上可以浏览到它。我们也可以在applicationHost.config看到:

    <site name="MySite" id="3">
      <application path="/" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="D:\MySite\www" />
        <virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
        <virtualDirectory path="/vdir_1/sub_dir1" physicalPath="D:\MySite\more_content" />
        <virtualDirectory path="/vdir_2/sub_dir1" physicalPath="D:\MySite\even_more_content" />
      </application>
    </site>
    

    将文件夹转换为应用程序:

    如果您刚刚将一个 ASP.NET 应用程序上传到您网站中的 /app_1 文件夹,并且您想将其变成自己的应用程序,我们会这样做:

    Application app = site.Applications.Add("/app_1", @"d:\MySite\www\app_1");
    // set application pool, otherwise it'll run in DefaultAppPool
    app.ApplicationPoolName = "MySite";
    serverManager.CommitChanges();    
    

    applicationHost.config 中我们可以看到添加了一个新的&lt;application&gt; 元素:

    <site name="MySite" id="3">
      <application path="/" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="D:\MySite\www" />
        <virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
        <virtualDirectory path="/vdir_1/sub_dir1" physicalPath="D:\MySite\more_content" />
        <virtualDirectory path="/vdir_2/sub_dir1" physicalPath="D:\MySite\even_more_content" />
      </application>
      <application path="/app_1" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="d:\MySite\www\app_1" />
      </application>
    </site>
    

    在 IIS 中我们看到:

    这相当于右键单击“转换为应用程序”。

    将应用程序添加到现有应用程序:

    将应用程序添加为现有应用程序的子应用程序非常简单。假设我们想让/app_1/sub_app_1 成为/app_1 的子应用程序:

    我们会这样做:

    Application app = 
      site.Applications.Add("/app_1/sub_app_1", @"d:\mysite\www\app_1\sub_app_1");
    app.ApplicationPoolName ="MySite";
    

    生成的配置如下所示:

    <site name="MySite" id="3">
      <application path="/" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="D:\MySite\www" />
        <virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
        <virtualDirectory path="/vdir_1/sub_dir1" physicalPath="D:\MySite\more_content" />
        <virtualDirectory path="/vdir_2/sub_dir1" physicalPath="D:\MySite\even_more_content" />
      </application>
      <application path="/app_1" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="d:\MySite\www\app_1" />
      </application>
      <application path="/app_1/sub_app_1" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="d:\mysite\www\app_1\sub_app_1" />
      </application>
    </site>
    

    在 IIS 中:

    将虚拟目录添加到应用程序:

    现在,如果我们想向这个应用程序添加一个虚拟目录,我们可以这样做:

    Application app = site.Applications.First(a => a.Path == "/app_1");
    app.VirtualDirectories.Add("/vdir_1", @"d:\MySite\other_content");
    

    applicationHost.config 中我们可以看到添加了一个新的&lt;virtualDirectory&gt; 元素:

    <site name="MySite" id="3">
      <application path="/" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="D:\MySite\www" />
        <virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
        <virtualDirectory path="/vdir_1/sub_dir1" physicalPath="D:\MySite\more_content" />
        <virtualDirectory path="/vdir_2/sub_dir1" physicalPath="D:\MySite\even_more_content" />
      </application>
      <application path="/app_1" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="d:\MySite\www\app_1" />
        <virtualDirectory path="/vdir_1" physicalPath="d:\MySite\other_content" />
      </application>
    </site>
    

    在 IIS 中我们看到:

    同样重要的是要注意虚拟路径 /vdir1 始终相对于包含应用程序的路径。

    将现有虚拟目录转换为应用程序:

    如果我们想将刚刚创建的虚拟目录 (/app_1/vdir1) 转换为应用程序怎么办?我们需要分两步完成:

    // Get the application
    Application app_1 = site.Applications.First(a => a.Path == "/app_1");
    // Find the virtual directory
    VirtualDirectory vdir_1 = app_1.VirtualDirectories.First(v => v.Path == "/vdir_1");
    // Remove it from app_1
    app_1.VirtualDirectories.Remove(vdir_1);
    // Create our application
    Application vdir_1_app = site.Applications.Add("/app_1/vdir_1", vdir_1.PhysicalPath);
    // set application pool, otherwise it'll run in DefaultAppPool
    vdir_1_app.ApplicationPoolName = "MySite";
    serverManager.CommitChanges();    
    

    生成的applicationHost.config 看起来像:

    <site name="MySite" id="3">
      <application path="/" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="D:\MySite\www" />
        <virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
        <virtualDirectory path="/vdir_1/sub_dir1" physicalPath="D:\MySite\more_content" />
        <virtualDirectory path="/vdir_2/sub_dir1" physicalPath="D:\MySite\even_more_content" />
      </application>
      <application path="/app_1" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="d:\MySite\www\app_1" />
      </application>
      <application path="/app_1/vdir_1" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="d:\MySite\other_content" />
      </application>
    </site>
    

    在 IIS 管理器中我们看到:

    将应用程序添加到现有虚拟目录:

    如果我们想将应用程序添加到虚拟目录会发生什么,它是如何工作的?在本例中,我们将向我们之前创建的虚拟目录/vdir_1/sub_dir1 添加一个应用程序。

    Application app = 
       site.Applications.Add("/vdir_1/sub_dir1/app_2", @"d:\mysite\other_content");
    app.ApplicationPoolName = "MySite";
    serverManager.CommitChanges();
    

    生成的配置如下所示:

    <site name="MySite" id="3">
      <application path="/" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="D:\MySite\www" />
        <virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
        <virtualDirectory path="/vdir_1/sub_dir1" physicalPath="D:\MySite\more_content" />
        <virtualDirectory path="/vdir_2/sub_dir1" physicalPath="D:\MySite\even_more_content" />
      </application>
      <application path="/app_1" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="d:\MySite\www\app_1" />
      </application>
      <application path="/app_1/vdir_1" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="d:\MySite\other_content" />
      </application>
      <application path="/vdir_1/sub_dir1/app_2" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="d:\mysite\other_content" />
      </application>
    </site>
    

    在 IIS 管理器中我们看到:

    将现有子文件夹转换为应用程序:

    最后一个例子,我们想把/other_apps/sub_app_1变成一个应用程序:

    我们的代码如下:

    Application app = 
       site.Applications.Add("/other_apps/sub_app_1", @"d:\mysite\other_content");
    app.ApplicationPoolName="MySite";
    serverManager.CommitChanges();
    

    结果配置:

    <site name="MySite" id="3">
      <application path="/" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="D:\MySite\www" />
        <virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
        <virtualDirectory path="/vdir_1/sub_dir1" physicalPath="D:\MySite\more_content" />
        <virtualDirectory path="/vdir_2/sub_dir1" physicalPath="D:\MySite\even_more_content" />
      </application>
      <application path="/app_1" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="d:\MySite\www\app_1" />
      </application>
      <application path="/app_1/vdir_1" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="d:\MySite\other_content" />
      </application>
      <application path="/vdir_1/sub_dir1/app_2" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="d:\mysite\other_content" />
      </application>
      <application path="/other_apps/sub_app_1" applicationPool="MySite">
        <virtualDirectory path="/" physicalPath="d:\mysite\other_content" />
      </application>
    </site>
    

    在 IIS 管理器中:

    希望这有助于解释站点、应用程序和虚拟目录之间的关系。

    【讨论】:

    • 太棒了,谢谢@Kev。值得一提的是,在转换为应用程序的说明下,我的一个安装程序将子目录创建为 VDir 而不是常规目录,因此当我运行该代码以将其转换为应用程序时,它给了我一个“目录已存在”。解决方案只是调用 API 以从 VirtualDirectories 集合中删除现有的 VDir(如果它在添加应用程序之前存在)。小物品,但可能值得包含在您的说明中。
    • @mike - 谢谢,很高兴这有帮助。今天我会修改帖子。 :)
    • 这是我见过的最好最详细的答案之一;干得好!
    • 教程之类的答案,有你Kev给力。
    • 出色的答案 - 感谢您投入所有时间和精力。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多