2010-11-16 120 views
1

注意:这个问题也可以在WiX mailing list找到。如何通过WiX 3.5检查是否存在IIS 7网站?

我需要能够根据网站的描述检查是否存在IIS7网站。如果网站不存在,我需要取消安装。如果网站存在,我想继续安装。我还需要能够保存网站的网站ID,以便我可以在卸载过程中使用它。

为了进行调试,我对网站的描述进行了硬编码。我没有看到在MSI日志文件中检查网站的任何迹象。这是我使用的代码:

<iis:WebSite Id="IISWEBSITE" Description="Default Web Site" SiteId="*"> 
     <iis:WebAddress Id="IisWebAddress" Port="1"/> 
</iis:WebSite> 

<Condition Message="Website [IISWEBSITE] not found."> 
     <![CDATA[IISWEBSITE]]> 
</Condition> 

使用ORCA我可以看到IIsWebAddress和IIsWebSite表添加到MSI。这些值是:

IIsWebsite

WEB:   IISWEBSITE 
Description: Default Web Site 
KeyAddress: IisWebAddress 
Id:   -1 

IIsWebAddress

Address: IisWebAddress 
Web_: IISWEBSITE 
Port: 1 
Secure: 0 

与上面的代码中,安装停止并显示错误消息 “未找到网站”。看来,IISWEBSITE永远不会被设置。虽然,我知道“默认网站”存在。我知道我必须错过什么,但是什么?

如何在IIS 7中执行简单的网站检查?

回答

0

我也有同样的问题。

我写了一个自定义操作来从注册表中检查IIS的版本。

上的注册表值的基础上创建虚拟目录

0

我写在Javascript自定义操作来做到这一点。如果您使用的是IIS7,那么您可以使用appcmd.exe工具,只需从Javascript中调用它即可获取网站列表。理论上来说,这很简单。但在实践中,你需要跳过一堆篮球。

这就是我想出了:

function RunAppCmd(command, deleteOutput) { 
    var shell = new ActiveXObject("WScript.Shell"), 
     fso = new ActiveXObject("Scripting.FileSystemObject"), 
     tmpdir = fso.GetSpecialFolder(SpecialFolders.TemporaryFolder), 
     tmpFileName = fso.BuildPath(tmpdir, fso.GetTempName()), 
     windir = fso.GetSpecialFolder(SpecialFolders.WindowsFolder), 
     appcmd = fso.BuildPath(windir,"system32\\inetsrv\\appcmd.exe") + " " + command, 
     rc; 

    deleteOutput = deleteOutput || false; 

    LogMessage("shell.Run("+appcmd+")"); 

    // use cmd.exe to redirect the output 
    rc = shell.Run("%comspec% /c " + appcmd + "> " + tmpFileName, WindowStyle.Hidden, true); 
    LogMessage("shell.Run rc = " + rc); 

    if (deleteOutput) { 
     fso.DeleteFile(tmpFileName); 
    } 
    return { 
     rc : rc, 
     outputfile : (deleteOutput) ? null : tmpFileName 
    }; 
} 



// GetWebSites_Appcmd() 
// 
// Gets website info using Appcmd.exe, only on IIS7+ . 
// 
// The return value is an array of JS objects, one per site. 
// 
function GetWebSites_Appcmd() { 
    var r, fso, textStream, sites, oneLine, record, 
     ParseOneLine = function(oneLine) { 
      // split the string: capture quoted strings, or a string surrounded 
      // by parens, or lastly, tokens separated by spaces, 
      var tokens = oneLine.match(/"[^"]+"|\(.+\)|[^ ]+/g), 
       // split the 3rd string: it is a set of properties separated by colons 
       props = tokens[2].slice(1,-1), 
       t2 = props.match(/\w+:.+?(?=,\w+:|$)/g), 
       bindingsString = t2[1], 

       ix1 = bindingsString.indexOf(':'), 
       t3 = bindingsString.substring(ix1+1).split(','), 
       L1 = t3.length, 
       bindings = {}, i, split, obj, p2; 

      for (i=0; i<L1; i++) { 
       split = t3[i].split('/'); 
       obj = {}; 
       if (split[0] == "net.tcp") { 
        p2 = split[1].split(':'); 
        obj.port = p2[0]; 
       } 
       else if (split[0] == "net.pipe") { 
        p2 = split[1].split(':'); 
        obj.other = p2[0]; 
       } 
       else if (split[0] == "http") { 
        p2 = split[1].split(':'); 
        obj.ip = p2[0]; 
        if (p2[1]) { 
         obj.port = p2[1]; 
        } 
        obj.hostname = ""; 
       } 
       else { 
        p2 = split[1].split(':'); 
        obj.hostname = p2[0]; 
        if (p2[1]) { 
         obj.port = p2[1]; 
        } 
       } 
       bindings[split[0]] = obj; 
      } 

      // return the object describing the website 
      return { 
       id   : t2[0].split(':')[1], 
       name  : "W3SVC/" + t2[0].split(':')[1], 
       description : tokens[1].slice(1,-1), 
       bindings : bindings, 
       state  : t2[2].split(':')[1] // started or not 
      }; 
     }; 

    LogMessage("GetWebSites_Appcmd() ENTER"); 

    r = RunAppCmd("list sites"); 
    if (r.rc !== 0) { 
     // 0x80004005 == E_FAIL 
     throw new Exception("ApplicationException", "exec appcmd.exe returned nonzero rc ("+r.rc+")", 0x80004005); 
    } 

    fso = new ActiveXObject("Scripting.FileSystemObject"); 
    textStream = fso.OpenTextFile(r.outputfile, OpenMode.ForReading); 
    sites = []; 

    // Read from the file and parse the results. 
    while (!textStream.AtEndOfStream) { 
     oneLine = textStream.ReadLine(); 
     record = ParseOneLine(oneLine); 
     LogMessage(" site: " + record.name); 
     sites.push(record); 
    } 
    textStream.Close(); 
    fso.DeleteFile(r.outputfile); 

    LogMessage("GetWebSites_Appcmd() EXIT"); 

    return sites; 
}