Here's an example script that demonstrates a typical installation:
DO WCONNECT SET CLASSLIB TO WEBSERVER ADDITIVE lcApplication = "MyApplication" *** Hardcoded values - these would normally come *** from some sort of UI (popup a form?) *** Deployment Path lcWebPath = LOWER(FULLPATH("..\web\")) lcServerType = "IIS6" *** Name of the virtual Web directory for IIS lcVirtual = lcApplication lcServerExe = lcApplication + ".exe" lcTempPath = ADDBS(SYS(2023)) + "wc" **** COM Configuration lcProgId = lcApplication + "." + lcApplication + "Server" lcDCOMUserName = "Interactive User" lcDCOMPassword = "" && Fill in if you're using a real account *** End stock parameters *** Prompt for a few of the main parameters - ideally this should be a form to *** prompt for all the inputs lcServerName = "LOCALHOST" lcServerName = InputForm(lcServerName,"The local IP Address or domain of the server to configure","IIS Configuration - Server Address",,,"") IF EMPTY(lcServerName) return ENDIF lcServerType = InputForm(lcServerType,"IIS Version (IIS5, IIS6, IIS7)","IIS Configuration - IIS Server Type",,,"") IF EMPTY(lcServerType) return ENDIF lcWebPath = InputForm(lcWebPath,"Location of the Web Directory","IIS Configuration - Web Directory",,,"") IF EMPTY(lcWebPath) return ENDIF *** Create Virtual Directory oIIS = CREATEOBJECT("wwWebServer") oIIS.cServerType = lcServerType oIIS.cIISVirtualPath = "IIS://" + lcServerName + "/W3SVC/1/ROOT" && IIS Schema path oIIS.cApplicationPool = "West Wind Web Connection" IF ISNULL(GETOBJECT(oIIS.cIIsVirtualPath)) showStatus( "Unable to connect to IIS Administration COM object." ) return ENDIF showStatus("creating virtual directory") IF !oIIS.CreateVirtual(lcVirtual,lcWebPath) showStatus("Unable to create virtual directory") RETURN ENDIF *** Do some custom work on the new virtual *** Turn off Anonymous Permissions to FORCE LOGINS for EVERY REQUEST * loVirtual = GETOBJECT(oIIs.cIISVirtualPath + "/" + lcVirtual) * loVirtual.AuthAnonymous = .F. * loVirtual.SetInfo() *** Assume wc.dll lives in BIN directory lcScriptDLL = lcWebPath + 'bin\wc.dll' showStatus("creating script maps") lcIISVirtual = oIIS.cIISVirtualPath + "/" + lcVirtual *** Create script maps to the DLL oIIS.CreateScriptMap('wc',lcScriptDll, lcIISVirtual) oIIS.CreateScriptMap('wcsx',lcScriptDll, lcIISVirtual) oIIS.CreateScriptMap('wwsoap',lcScriptDll, lcIISVirtual) oIIS.CreateScriptMap('aspx',lcScriptDll, lcIISVirtual) showStatus("registering ISAPI dll in IIS") *** In IIS6 and later we have to register any DLLs with IIS IF LOWER(lcServerType) = "iis" AND LOWER(lcServerType) > "iis5" *** Add the DLL as a registered loIIS = CREATEOBJECT("wwIISAdmin") loIIS.cPath = "IIS://" + lcServerName + "/W3SVC" loIIS.AddRegisteredExtension(lcScriptDll,"West Wind Web Connection") loIIS = .f. ENDIF *** Create Temp Directory IF !ISDIR(lcTempPath) MD (lcTempPath) ENDIF *** Set permissions for IUSR_ Virtual loVirtual = GETOBJECT(oIIS.cIISVirtualPath) lcAnonymousUserName = loVirtual.AnonymousUserName loVirtual = .f. *!* *** Set access on the Web directory IF !EMPTY(lcWebPath) *** Read writes - wwUtils.SetAcl() llResult = SetAcl(lcWebPath,lcAnonymousUserName,"R",.t.) ENDIF *** Not required for Web Connection 5.x - wc.dll runs as SYSTEM * IF lcTempPath * *** Full rights in the temp directory * llResult = SetAcl(lcTempPath,lcAnonymousUserName,"F",.t.) * ENDIF showStatus("Register Com object") *** Register COM object and configure DCOM programmatically IF !EMPTY(lcProgId) wait window "Registering COM server" nowait lcCommand = "run " + lcServerExe + " /regserver" &lcCommand IF ISWinNT() IF !EMPTY(lcDCOMPassword) AND !FILE("DCOMPermissions.exe") MESSAGEBOX("DCOMPermissions.exe file is missing" + CHR(13) +; "Can't configure DCOM settings. Please configure manually.",48,"DCOM Settings") ELSE DO DCOMCNFGServer WITH lcProgId, lcDCOMUserName, lcDCOMPassword IF FILE("DCOMPermissions.exe") loAPI = CREATE("wwAPI") lcMachineName = loAPI.GetComputerName() DCOMLaunchPermissions(lcProgId,"Administrators") DCOMLaunchPermissions(lcProgId,"SYSTEM") DCOMLaunchPermissions(lcProgId,"INTERACTIVE") ENDIF ENDIF ENDIF ENDIF FUNCTION showStatus(lcMessage) WAIT WINDOW NOWAIT (lcMessage) ENDFUNC
This script is not generic obviously, but it can be customized quite easily in a few places for most configurations. You might want to add or remove some script maps (like ASPX which was used for this particular project) or you might need additional settings applied say to the virtual directory. Note that the code even does some custom ADSI configuration for setting security - in this case it's removing Anonymous user access from the app so that every user is forced to log in with Windows credentials.
The beauty of this sort of script is that once you have your configuration set up it's very easy to run it for a first time config or even to reconfigure if something should get accidentally removed.
If you want to deploy this you can either choose to build an EXE out of this small program by adding to a project and compiling into an EXE, or maybe even easier by adding it to your main server EXE itself with code like the following in the startup program (like wcDemoMain.prg):
************************************************************************ * MyApplicationMain ****************************** *** Created: 06.05.2008 *** Function: Web Connection Mainline program. Responsible for setting *** up the Web Connection Server and get it ready to *** receive requests in file messaging mode. ************************************************************************ LPARAMETERS lcAction IF !EMPTY(lcAction) IF UPPER(lcAction) == "CONFIG" DO configurationScript RETURN ENDIF ENDIF *** This is the file based start up code that gets *** the server form up and running #INCLUDE WCONNECT.H …
With this code the configuration script is now part of the server and you can simply do:
YourServer.exe Config
To run the configuration code. Simple and self contained and makes the configuration script available along with your EXE always.
AppRoot ApplicationFiles (EXE,Ini files, Web Connection Tools/html/Scripts/Template folders) Web (the Web Virtual directory where WCSX etc. scripts and templates live) Data (Optional data directory if you're using VFP data)
Note that in this scenario the web folder is NOT underneath the actual Web root (ie. c:\inetpub\wwwroot), but this works perfectly fine as long as the path is configured properly and permissions are set appropriately specifically for the IIS anonymous user (ie. IIS_YourMachine) to have read/execute access. The configuration script above handles this automatically by looking up the Anonymous account and setting permissions on the Web folder for this account.
For a more elaborate example of a front end you can take a look at the wwAppWizard class (especially the Configure Server method) and the ConfigureServer class in wcSetup.vcx. The source code for these classes is provided and you can build your own wizards based on them if you choose. Or you can build a much simpler form interface to customize with just the 4 or 5 configurable options to present to the user. In your own applications most options other than the install path are probably fixed so the user interface can be pretty simple for a front end.
Note that source code for the Setup, New Project and Configuration Wizards is also available - you can customize those Wizards with custom logos and customized code. The actual configuration code resides in wwAppWizard and you can override any of the individual methods as you see fit to customize setup behaviors.