I have a script CustomAction (Yes, I know all about the opinions that say don't use script CustomActions. I have a different opinion.)
I'd like to run a mand, and capture the output. I can do this using the WScript.Shell COM object, then invoking shell.Exec()
. But, this flashes a visible console window for the executed mand.
To avoid that, I understand I can use the shell.Run()
call, and specify "hidden" for the window appearance. But .Run()
doesn't give me access to the StdOut of the executed process, so that means I'd need to create a temporary file and redirect the exe output to the temp file, then later read that temp file in script.
Some questions:
is this gonna work?
How do I generate a name for the temporary file? In .NET I could use a static method in the System.IO namespace, but I am using script here. I need to insure that the use has RW access, and also that no anti-virus program is going to puke on this.
Better ideas? I am trying very hard to avoid C/C++.
I could avoid all this if there were a way to query websites in IIS7 from script, without resorting to the IIS6 Compatibility pack, without using .NET (Microsoft.Web.Administration.ServerManager), and without execing a process (appcmd list sites). I already asked a separate question on that topic; any suggestions on that would also be appreciated.
I have a script CustomAction (Yes, I know all about the opinions that say don't use script CustomActions. I have a different opinion.)
I'd like to run a mand, and capture the output. I can do this using the WScript.Shell COM object, then invoking shell.Exec()
. But, this flashes a visible console window for the executed mand.
To avoid that, I understand I can use the shell.Run()
call, and specify "hidden" for the window appearance. But .Run()
doesn't give me access to the StdOut of the executed process, so that means I'd need to create a temporary file and redirect the exe output to the temp file, then later read that temp file in script.
Some questions:
is this gonna work?
How do I generate a name for the temporary file? In .NET I could use a static method in the System.IO namespace, but I am using script here. I need to insure that the use has RW access, and also that no anti-virus program is going to puke on this.
Better ideas? I am trying very hard to avoid C/C++.
I could avoid all this if there were a way to query websites in IIS7 from script, without resorting to the IIS6 Compatibility pack, without using .NET (Microsoft.Web.Administration.ServerManager), and without execing a process (appcmd list sites). I already asked a separate question on that topic; any suggestions on that would also be appreciated.
Share Improve this question edited May 23, 2017 at 12:25 CommunityBot 11 silver badge asked Mar 22, 2011 at 17:04 CheesoCheeso 193k106 gold badges485 silver badges734 bronze badges 4- 1 downvote, huh? Is this a bad question to ask? – Cheeso Commented Mar 22, 2011 at 23:39
- Well, you start off by saying you are going to use JScript despite expert advice you have been given then start to mention fragility concerns that are inherent in the use of JScript Custom actions and also say that you are looking for "Better Ideas". If you want a better idea, do a google search for "wix list web sites dtf". IIS 7 will already have .NET and if the Class he is using requires Compatibility mode then reuse all the infrastructure and just pick a different class. – Christopher Painter Commented Mar 22, 2011 at 23:56
- 1 Thank you. Not all IIS7 have .NET; there is a server core option which lacks .NET, as far as I am aware. If there is no good answer to the question, then I suppose that is the answer, but I don't agree that it makes the question a bad one. You're entitled to your opinion, though. Regarding script being a "bad idea" - the specific reasons he identified for not using it, have never affected me. It works, it's convenient and easy to develop. If the objections against script are irrelevant, then why should I avoid it? – Cheeso Commented Apr 4, 2011 at 17:51
- Your argument is a little like saying your house has never burned down when you stuck a penny in the fuse box and your lights are working so what's the big deal? I have personally experienced the pain points that Rob mentions and I can vouch that it's not a best practice. I've been doing installs full time for 15 years and I speak from experience on this subject. – Christopher Painter Commented Apr 4, 2011 at 20:33
1 Answer
Reset to default 11Answering my own question...
yes, this is going to work.
Use the Scripting.FileSystemObject thing within Javascript. There's a
GetTempName()
method that produces a file name suitable for temporary use, and aGetSpecialFolder()
method that gets the location of the temp folder. There's even aBuildPath()
method to bine them.so far I don't have any better ideas.
Here's the code I used:
function GetWebSites_IIS7_B()
{
var ParseOneLine = function(oneLine) {
...regex parsing of output...
};
LogMessage("GetWebSites_IIS7_B() ENTER");
var shell = new ActiveXObject("WScript.Shell");
var fso = new ActiveXObject("Scripting.FileSystemObject");
var tmpdir = fso.GetSpecialFolder(SpecialFolders.TemporaryFolder);
var tmpFileName = fso.BuildPath(tmpdir, fso.GetTempName());
var windir = fso.GetSpecialFolder(SpecialFolders.WindowsFolder);
var appcmd = fso.BuildPath(windir,"system32\\inetsrv\\appcmd.exe") + " list sites";
// use cmd.exe to redirect the output
var rc = shell.Run("%spec% /c " + appcmd + "> " + tmpFileName, WindowStyle.Hidden, true);
// WindowStyle.Hidden == 0
var ts = fso.OpenTextFile(tmpFileName, OpenMode.ForReading);
var sites = [];
// Read from the file and parse the results.
while (!ts.AtEndOfStream) {
var oneLine = ts.ReadLine();
var line = ParseOneLine(oneLine);
LogMessage(" site: " + line.name);
sites.push(line);
}
ts.Close();
fso.DeleteFile(tmpFileName);
return sites;
}