PageBox |
|
FAQ | Dev site | .NET version | Customization | Install | Grid | Active Naming | Grid API |
PageBox for .NET customization
You can download PageBox and its repository for .NET in Zip format:
The repository of PageBox for .NET is made of the following files:
Name | Purpose |
---|---|
Publisher page | |
Server code of the publisher page | |
Subscriber page | |
Server code of the subscriber page | |
Server code of global.asax | |
Login form | |
Server code of login-form.aspx | |
Class describing a subscribed PageBox | |
Class describing the subscribed PageBoxes of a Repository | |
Class describing the publications of a Repository | |
Class responsible of the presentation deployment | |
Web service proxy | |
CSS used to display repository pages | |
PageBox logo | |
PageBox mail icon | |
Example of configuration file | |
Example of authorization file (users allowed to publish archives) | |
Archive subscriber page | |
Code of archive subscriber page | |
Page of archive selection (for archive subscriber) | |
Code of archive selection page (for archive subscriber) | |
Download page | |
Code of download page | |
Log display page | |
Code of log display page | |
Log writer | |
Code of Retry.asmx Web service | |
Code of Query.asmx Web service of the Repository | |
Datagrid for aselect (multiselection) | |
Main class of Cleanup Windows service | |
Worker thread invoking the Retry Web service | |
Web service proxy | |
Generated by Visual Studio for the installation of the Windows service | |
Example of configuration file for retries |
The Repository archive also includes a TestRepoCleanup directory that you can use
To modify the Windows service (even with .NET it is still not easy to test the former NT services)
To set the service cleanup.xml path and logging mode
TestRepoCleanup contains the following files:
Name | Purpose |
---|---|
Window form application | |
Worker thread invoking the Retry Web service | |
Web service proxy | |
Example of configuration file for retries |
PageBox for .NET is made of the following files:
Name | Purpose |
---|---|
PageBox page | |
Code of PageBox page | |
Code of Deploy.asmx Web service | |
Code of Query.asmx Web service | |
Proxy of the RepoQuery Web service | |
Server code of Global.asax | |
unzip.exe | From Infozip. Example of archive installation |
Example of archive installation script (DOS) | |
Example of JavaScript installation and de-installation script (WSH) | |
Example of archive de-installation script (DOS) | |
CSS used to display repository pages | |
PageBox logo | |
PageBox mail icon | |
Example of configuration for archive installation/de-installation | |
Log display page | |
Code of log display page | |
Log writer | |
ActiveNaming Web service | |
Proxy of the ActiveNaming Web service |
The Grid API of PageBox for .NET (pageboxgrid.zip) is made of the following files:
Name | Purpose |
---|---|
ActiveProxy.cs | Proxy of the ActiveNaming Web service |
Grid.cs | Grid API class |
Log.cs | Class responsible for error logging |
MulticastListener.cs | Listener for multicast datagrams |
POPListener.cs | Listener for mails |
UDPAddressPort.cs | Used to implement Hashtable key on (UDP address, port) |
UDPListener.cs | Listener for UDP datagrams |
UDPQueue.cs | Classes used by MulticastListener and UDPListener |
The ActiveNaming Web service is described in the Active Naming documentation and in the Grid presentation.
The Grid API is described in the Grid API documentation and in the Grid presentation.
The Subscriber class contains archs, an associative array of the presentations deployed or pending for deployment.
Subscriber has three methods:
A constructor without parameter to create a new Subscriber
A constructor with an XmlReader to restore a Subscriber from subscribers.xml
WriteXml to serialize a Subscriber in subscribers.xml
The RepoSubs class contains subscribers, an associative array of the subscribing PageBoxes and asubscribers, an associative array of the archive subscribers.
RepoSubs has eleven methods:
A constructor with an XmlReader to restore a RepoSubs from subscribers.xml. To restore subscribers and asubscribers, it calls restoreSubs
restoreSubs restores a associative table from subscribers.xml
WriteXml serializes a RepoSubs in subscribers.xml
subscribe adds a subscriber to the repository
unsubscribe removes a subscriber from the repository
asubscribe adds an archive subscriber to the repository
unasubscribe removes a archive subscriber from the repository
add adds a presentation to an archive subscriber
delete removes a presentation from an archive subscriber
cleanup invokes cleanup2 for subscribers and archive subscribers. cleanup is invoked by the Retry Web Service
cleanup2 tries to remove pending state. If an archive is in "pending deploy" cleanup2 deploys the archive again. If an archive is in "pending undeploy" cleanup2 undeploys the archive again. If cleanup2 succeeded to undeploy all archives deployed on a subscribing PageBox and if this PageBox is in "pending unsubscribe" state cleanup2 removes the PageBox from the subscriber list.
When a new PageBox is subscribed, it receives all presentations defined in RepoArchs.
RepoSubs manages subscribers.xml. Here is an example:
<?xml version="1.0"?> <RepoSubs> <subscribers> <entry> <url>127.0.0.1/PageBox/PageBox/Deploy.asmx</url> <Subscriber> <arch> <name>art030_UploadFile.zip</name> <status>art030_UploadFile.zip installed</status> </arch> <arch> <name>MasterDetailDPLCHK.zip</name> <status>MasterDetailDPLCHK.zip installed</status> </arch> <state>active</state> </Subscriber> </entry> <entry> <url>127.0.0.1/PageBox/PageBox2/Deploy.asmx</url> <Subscriber> <arch> <name>art030_UploadFile.zip</name> <status>art030_UploadFile.zip installed</status> </arch> <arch> <name>MasterDetailDPLCHK.zip</name> <status>MasterDetailDPLCHK.zip installed</status> </arch> <state>active</state> </Subscriber> </entry> </subscribers> <asubscribers /> </RepoSubs> |
The RepoArchs class contains four associative arrays:
archives contains the archive names and owners
docs contains the archive names and documentation URLs
administrators contains the administrator user ids
publishers contains the publisher user ids
RepoArch has nine methods:
A constructor with an XmlReader to restore archives and docs from archives.xml. To restore subscribers and asubscribers, it calls restoreHash2
restoreAuth restores administrators and publishers from authorization.xml. It calls restoreHash to restore administrators and publishers
restoreHash restores a user array (administrators or publishers) from authorization.xml
restoreHash2 restores an associative table from archives.xml
WriteXml serializes associative tables in archives.xml
add adds an archive to the repository
delete removes an archive from the repository
isAdministrator returns true if a user is an administrator
isPublisher returns true if a user is a publisher
When a new presentation is added, it is deployed on every subscriber and added to the Subscriber objects. Presentations are not automatically added to archive subscribers but when an archive subscriber has subscribed a presentation, it receives presentation updates.
RepoArchs manages archives.xml. Here is an example:
<?xml version="1.0"?> <RepoArchs> <archives> <entry> <arch>art030_UploadFile.zip</arch> <val>admin</val> </entry> <entry> <arch>MasterDetailDPLCHK.zip</arch> <val /> </entry> </archives> <docs> <entry> <arch>art030_UploadFile.zip</arch> <val>http://localhost/home2/php/php-index.html</val> </entry> <entry> <arch>MasterDetailDPLCHK.zip</arch> <val>http://localhost/home2/php/php-index.html</val> </entry> </docs> </RepoArchs> |
The Deployer class has two static methods:
deploy deploys a presentation on a PageBox using the add method of the Deploy Web Service
undeploy undeploys a presentation on a PageBox using the delete method of the Deploy Web Service
RepoArchs and RepoSubs extend Deployer and invoke its methods.
Deploy.cs is a SOAP proxy. It has been generated from the Deploy Web service of PageBox using wsdl.exe. The constructor has been modified to set the Web service URL, which has to be the subscriber URL.
Global class contains two static members, subRep, a RepoSubs singleton and archRep, a RepoArchs singleton. Global restores archRep and subRep at the first request performed on the Repository application in Application_BeginRequest.
Application_BeginRequest calls restore to restore subRep and archRep.
restore uses RepoArchs and RepoSubs’s constructors with an XmlReader to restore subRep and archRep from subscribers.xml and archives.xml.
Global class contains two methods, saveSubRep to save subRep on subscribers.xml and saveArchRep to save archRep on archives.xml. These methods call the WriteXml methods of RepoSubs and RepoArchs.
The SubscriberWF class manages a form that
Lists the Repository subscribers using a DataGrid
Allows adding and removing subscribers
The bind method binds an ArrayList to the Datagrid. This ArrayList contains SubscriberEntry objects.
bind populates the ArrayList from RepoSubs.subscribers.
bind is called by Page_Load, subscriberDB_unsubscribe, Form1_subscribe, Form1_unsubscribe, Form1_force, Form1_refresh.
subscriber.aspx provides two buttons to remove subscribers Unsubscribe and Force and a button to refresh the Datagrid, refresh. When the user clicks one of these buttons, Form1_subscribe, Form1_unsubscribe, Form1_force or Form1_refresh is invoked.
Form1_subscribe invokes RepoSubs.subscribe.
Form1_unsubscribe and Form1_force invoke RepoSubs.unsubscribe.
Force allows removing a PageBox that doesn’t exist (anymore) whereas Unsubscribe keeps the subscriber in "pending unsubscribe" state. In that state the subscriber doesn’t receive new archives.
The Datagrid rows have also two buttons, unsub and force.
In InitializeComponent we added subscriberDB_unsubscribe to the Datagrid’s ItemCommand as DataGridCommandEventHandler. When the user clicks either on unsub or force buttons, subscriberDB_unsubscribe is called. subscriberDB_unsubscribe calls RepoSubs.unsubscribe.
The publisher class manages a form that
Lists the uploaded presentations and batchs using a Datagrid.
Allows uploading and removing presentations and batchs.
If you put authentication in place then only publishers and administrators can use that form and a publisher can only see the presentations and batchs that she or he has published.
A user is a publisher if its user id is defined in RepoArchs.publishers.
A user is an administrator if its user id is defined in RepoArchs.administrators.
RepoArchs restores publishers and administrators from authorization.xml. Here is an example of authorization.xml:
<authorization> <administrators> <user>admin</user> </administrators> <publishers> <user>publisher1</user> <user>publisher2</user> </publishers> </authorization> |
authorization.xml handles role authorizations. Authentication is defined in web.config. By default we use Form based authentication with login-form.aspx:
<authentication mode="Forms"> <forms loginUrl="login-form.aspx"> <credentials passwordFormat="Clear"> <user name="admin" password="admin" /> <user name="subscriber1" password="subscriber" /> <user name="subscriber2" password="subscriber" /> <user name="publisher1" password="publisher" /> <user name="publisher2" password="publisher" /> </credentials> </forms> </authentication> <authorization> <deny users="?" /> </authorization> |
It is very important to define the <authorization> element and to forbid unauthenticated access to the Repository application.
When authentication is in place:
In case of publication, publisher registers the user id as the owner of the presentation
A user B cannot publish a presentation with the same name as a presentation previously published by a user A
update.aspx displays the owner of deployed archives
The bind method binds an ArrayList to the Datagrid. This ArrayList contains PublisherEntry objects.
bind populates the ArrayList from RepoArchs.archives and RepoArchs.docs.
bind is called by Page_Load, archUpload, refresh, archiveDB_delete.
publisher.aspx provides a button to upload archives Upload and a button to refresh the Datagrid, Refresh. When the user clicks one of these buttons, archUpload or refresh is invoked.
archUpload processes POST method upload as defined in RFC 1867. The upload code is quite simple:
string arch = archFile.PostedFile.FileName; int pos = arch.LastIndexOf("\\"); arch = arch.Substring(pos + 1); if (!Directory.Exists(Global.archRep.downloadPath)) Directory.CreateDirectory(Global.archRep.downloadPath); archFile.PostedFile.SaveAs(Global.archRep.downloadPath + arch); LabStatus.Text = Global.archRep.add(arch, owner, docURL.Value); bind(); |
archUpload saves the uploaded file in downloadPath, which is Repository-Directory\..\download as defined in Global.asax.cs with a Repository name which is the same as the uploaded file (arch). Then it calls RepoArchs.add to add the archive to RepoArchs.archives and trigger the deployment of the presentation/batch on subscribers.
Beside the presentation location, publisher.aspx allows specifying the URL of the presentation documentation. archUpload retrieves it in docURL.value.
The Datagrid rows have also two buttons, Delete and Force.
In InitializeComponent we added archiveDB_delete to the Datagrid’s ItemCommand as DataGridCommandEventHandler. When the user clicks either on Delete or Force buttons, archiveDB_delete is called. archiveDB_delete calls RepoArchs.delete.
In both cases publisher send an undeploy(presentation) to all subscribers and removes the presentation file from the repository. If the undeploy succeeds, the presentation is removed from the archive list of the subscriber.
If the undeploy fails for one subscriber:
The presentation is removed from the archive list of the subscriber in case of Force
The presentation is kept in the archive list of the subscriber in case of Delete
The asubscriber class is very similar to subscriber.aspx.cs. It manages a form that
Lists the Archive subscribers of the Repository using a DataGrid
Allows adding and removing Archive subscribers
The bind method binds an ArrayList to the Datagrid. This ArrayList contains SubscriberEntry objects.
bind populates the ArrayList from RepoSubs.subscribers.
bind is called by Page_Load, subscriberDB_handle, Form1_subscribe, Form1_unsubscribe, Form1_force, Form1_refresh.
asubscriber.aspx provides two buttons to remove subscribers Unsubscribe and Force and a button to refresh the Datagrid, refresh. When the user clicks one of these buttons, Form1_subscribe, Form1_unsubscribe, Form1_force or Form1_refresh is invoked.
Form1_subscribe invokes RepoSubs.asubscribe.
Form1_unsubscribe and Form1_force invoke RepoSubs.unasubscribe.
Force allows removing a PageBox that doesn’t exist (anymore) whereas Unsubscribe keeps the subscriber in "pending unsubscribe" state. In that state the subscriber doesn’t receive new archives.
The Datagrid rows have also two buttons, unsub and force.
In InitializeComponent we added subscriberDB_handle to the Datagrid’s ItemCommand as DataGridCommandEventHandler. When the user clicks either on unsub or force buttons, subscriberDB_handle is called. subscriberDB_handle calls RepoSubs.unasubscribe.
The Datagrid rows also contain a link to the aselect page. This link is created in asubscriber.aspx by
<asp:HyperLinkColumn HeaderText=" " ItemStyle-Width="7%" Text="Archives" DataNavigateUrlField="PageBox" DataNavigateUrlFormatString="aselect.aspx?subscriber={0}"/>
When you click on such a link, aselect is invoked in GET mode with a subscriber parameter containing the URL of the PageBox Web service.
aselect.aspx.cs manages a form that:
Lists the repository archives with a checkbox checked when the archive is deployed on this Archive subscriber
Allows adding or removing archives on the subscription
The form operates by delta:
If you check a checkbox the corresponding archive is deployed
If you uncheck a checkbox the corresponding archive is undeployed
You can make multiple changes before submitting the changes
To support this feature we use a MultiGrid class that extends DataGrid.
MultiGrid is based on the article of Dino Esposito published in the MSDN issue of January 2002.
It includes two changes:
The BindName method of SelectColumnTemplate sets the checkbox after the archive status (deployed/not deployed)
The SelectedItems property of MultiGrid returns an array of SelectedEntry objects. A SelectedEntry object contains the checkbox status and the row number
The bind method binds an ArrayList to the MultiGrid. This ArrayList contains SelectorEntry objects.
bind populates the ArrayList from RepoArchs.archives and RepoArchs.docs.
bind is called by Page_Load and Form1_refresh.
Form1_refresh reads SelectedItems, enumerates the archives and adds or remove archives on the subscription list accordingly.
download.aspx allows downloading presentations from Repositories without subscription:
When the presentation is updated, it is not deployed on the download site.
The download site doesn’t need a PageBox.
The download class manages a form that lists the uploaded presentations and batches using a Datagrid.
It implements one method, Page_Load that populates an ArrayList from RepoArchs.archives and RepoArchs.docs and binds it to the Datagrid. This ArrayList contains DownloadEntry objects.
A DownloadEntry contains both the presentation name (Archive) and download URL (ArchiveURL).
download.aspx provides a link to download presentations and batches, defined with:
<asp:HyperLinkColumn Target="_self" DataNavigateUrlField="ArchiveURL" DataTextField="Archive" ItemStyle-Width="28%" HeaderText="Archive"/>
Log.cs provides a write static method. write writes on log.rep entries that contain:
The time when write was invoked
The user and IP address that triggered the write invocation
The invoked method name, parameter and response
audit.aspx manages a form that displays log.rep and allows removing log.rep.
If you put authentication in place then only administrators can use that form.
The audit class implements two methods, clear and include.
Both methods first check that the user is an administrator.
clear removes the log.rep file.
include calls Response.WriteFile("log.rep")
clear is invoked through the Clear button.
include is invoked by <% include(); %>.
If it is properly configured, RepoCleanup calls the Retry.asmx every 30 minutes to retry pending deploys and undeploys. With this mechanism PageBox for .NET can cope with transient conditions such as Pagebox server reboot.
Because Retry.asmx is implemented as a Web Service a single RepoCleanup can monitor a set of Repositories on different machines.
Retry.asmx invokes the cleanup method of RepoSubs.cs.
Form based authentication, which is the preferred authentication scheme for the Repository, is not suitable for Web services. Therefore Retry.asmx is installed on a WebServices subdirectory of the repository.
WebServices contains a specific web.config that disables form-based authentication:
<configuration> <system.web> <authorization> <allow users="?" /> </authorization> </system.web> </configuration> |
Retry.asmx implements a custom authentication and authorization mechanism consistent with the rest of the Repository: only Repository administrators are allowed to issue cleanup requests. This mechanism is quite simple.
public string Cleanup(string user, string password) { if (!FormsAuthentication.Authenticate(user, password) || !Global.archRep.isAdministrator(user)) return "Retry.Cleanup failed: invalid credentials"; Global.subRep.cleanup(); return "Retry.Cleanup performed"; } |
Retry.asmx has a single method, Cleanup whose parameters are the user name and password to check
Cleanup uses FormsAuthentication.Authenticate to check if the user is defined and if its password is correct
Then Cleanup checks if the user is a Repository administrator
If the user credentials are OK, Cleanup calls the RepoSub’s cleanup method
RepoQuery has two methods:
GetSubscribers, the single method of the RepoQuery Web service. GetSubscribers returns an array that contains the URL of all subscribers and archive subscribers to a presentation but the requesting subscriber. GetSubscriber is called by the Query Web service of PageBox. GetSubscribers invokes the populate method to retrieve subscribers or archive subscribers.
populate enumerates the subscribers or archive subscribers and select the subscribers to the presentation
The PbArch class describes presentations and batchs deployed on a PageBox.
PbArch contains three associative tables:
archives. archives contains Archive objects and describes deployed archives
inflate. inflate contains InstallCommand objects and describes supported extensions and how to install a presentation with a given extension
remove. remove also contains InstallCommand objects and describes how to uninstall a presentation with a given extension
The InstallCommand class has three fields:
cmd
paramPrefix
useShell
To process a command, PbArch uses a ProcessStartInfo object:
ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = ic.cmd; psi.UseShellExecute = ic.useShell; psi.Arguments = ic.paramPrefix + Global.path + "\\" + a; Process p = Process.Start(psi); |
A command has a mandatory parameter, which is the archive path.
The parameter string is built like this:
Parameter-prefix + archive-directory + "\\" + archive-name |
You can put more than one parameter in Parameter-prefix but they must be followed by the archive full path.
restorePbCmd restores inflate and remove associative tables from pbCmd.xml. To restore inflate or remove, it invokes the restoreHash method.
Here is an example of pbCmd.xml file:
<commands> <inflate> <entry> <extension>.zip</extension> <command>inflate.js</command> <param-prefix>/arch:</param-prefix> <use-shell>true</use-shell> </entry> <entry> <extension>.jar</extension> <command>-</command> <param-prefix>-</param-prefix> <use-shell>true</use-shell> </entry> </inflate> <remove> <entry> <extension>.zip</extension> <command>inflate.js</command> <param-prefix>/del /arch:</param-prefix> <use-shell>true</use-shell> </entry> <entry> <extension>.jar</extension> <command>-</command> <param-prefix>-</param-prefix> <use-shell>true</use-shell> </entry> </remove> </commands> |
When the PageBox receives a deployment request for an archive xxxx.zip, it will call a WSH script
inflate.js /arch:archive-directory\\xxxx.zip
When the PageBox receives a undeployment request for an archive xxxx.zip, it will call a WSH script
inflate.js /del /arch;archive-directory\\xxxx.zip
When the PageBox receives a deployment request for an archive xxxx.jar, it won’t call a script because "-" stands for "Just copy this archive".
Here is an example of command (inflate.js):
var argsNamed = WScript.Arguments.Named; if (argsNamed.Exists("arch")) { var arch = argsNamed.Item("arch"); var pos = arch.lastIndexOf("."); var dir = arch.substring(0, pos); var sh = new ActiveXObject("WScript.Shell"); if (argsNamed.Exists("del")) { var fso = new ActiveXObject("Scripting.FileSystemObject"); fso.DeleteFolder(dir); // WScript.Echo("rmdir /S /Q " + dir); } else { sh.exec("unzip -o " + arch + " -d " + dir); // WScript.Echo("unzip -o " + arch + " -d " + dir); } } |
The archives associative table contains Archive objects.
The Archive class maintains the download location, the owner, size, upload time, documentation URL and state of the archive. Archive has a constructor to create a new Archive object, a constructor to restore an Archive object from PbArchives.xml (with a XmlReader parameter) and a method WriteXml to serialize onto PbArchives.xml.
The PbArchs constructor with a XMLReader parameter restores the archives associative table from PbArchive.xml whereas PbArchs’ WriteXml serializes the archive associative table onto PbArchives.xml.
PbArchive.xml looks like this:
<?xml version="1.0"?> <PbArchs> <archives> <entry> <arch>MasterDetailDPLCHK.zip</arch> <Archive> <downloadURL>127.0.0.1/download/</downloadURL> <owner>publisher1</owner> <size>16207</size> <date>2002-02-16T18:04:34.0047628+01:00</date> <docURL>http://agrandem/home2/cuckoo/cuckoo-pres.html</docURL> </Archive> </entry> </archives> </PbArchs> |
PbArchs has two other methods:
add. add adds a presentation to the archives associative table, downloads and installs the presentation
delete. delete removes a presentation from the archives associative table, removes and uninstalls the presentation
Global class contains a static member, pbArchives, a PbArchs singleton. Global restores pbArchives at the first request performed on the Repository application in Application_BeginRequest.
Application_BeginRequest calls restore to restore pbArchives.
restore uses PbArchs’ constructor with an XmlReader to restore pbArchives from pbArchives.xml.
Global class contains a savePbArchives method to save pbArchives on pbArchives.xml. This method call the WriteXml method of PbArchs.
Deploy.asmx is the deployment Web service.
Deploy.asmx.cs implements two Web methods, add that invokes the add method of the PbArchs singleton and delete that invokes the delete method of the PbArchs singleton.
The update class manages a form that lists the deployed presentations
The Page_Load method binds an ArrayList to the Datagrid. This ArrayList contains UpdateEntry objects.
Page_Load populates the ArrayList from PbArchs.archives.
Log.cs provides a write static method. write writes on log.html entries that contain:
The time when write was invoked
The user and IP address that triggered the write invocation
The invoked method name, parameter and response
audit.aspx manages a form that displays log.rep and allows removing log.html.
The audit class implements two methods, clear and include.
clear removes the log.html file.
include calls Response.WriteFile("log.html")
clear is invoked through the Clear button.
include is invoked by <% include(); %>.
Query.asmx has a single method of the Query Web service, GetSubscribers.
GetSubscribers retrieves the URL of the Repository RepoQuery Web service, invokes this RepoQuery Web service to get the URLs of all other subscribers and archive subscribers to the presentation and returns this list to the requestor – typically a presentation or application installed by the PageBox.
RepoCleanup is a Windows service (what used to be called a NT service).
RepoCleanup manages a set of Repositories.
Every 30 minutes RepoCleanup calls the Retry.asmx of every Repository that it knows to retry pending deploys and undeploys. With this mechanism PageBox for .NET can cope with transient conditions such as Pagebox server reboot.
Cleanup.cs is the core class of the Windows service. It implements two methods:
OnStart invoked when the Windows service is started
OnStop invoked when the Windows service is stopped
OnStart first retrieves the full path of the configuration file (cleanup.xml) and the logging mode.
It first looks in the registry.
As a regular Windows service, Cleanup is defined in the HKEY_LOCAL_MACHINE hive in SYSTEM\CurrentControlSet\Services\Cleanup.
OnStart expects to find the configuration path in SYSTEM\CurrentControlSet\Services\Cleanup\Parameters\ConfigFile and the logging mode in SYSTEM\CurrentControlSet\Services\Cleanup\Parameters\LogDebug.
Then OnStart looks at the startup parameters. It expects to find the path and optionally the logging mode.
If the path is not set either in the registry or as a startup parameter, OnStart writes an error on the Application event log with RepoCleanup as source:
Cleanup.OnStart service without startup parameter (cleanup.xml full path)
If the startup parameters are set, OnStart creates or updates the corresponding registry entries.
Then OnStart creates a CleanupThread and a worker thread where the ThreadRun method of CleanupThread will run.
ThreadRun waits 30 minutes or for a pulse. Then it checks a toStop Boolean. It toStop is true, it terminates. OnStop just sets toStop and issues the pulse to gracefully terminate the worker thread.
CleanupThread implements
A constructor that restores the configuration from cleanup.xml
Two logging methods, error and log
ThreadRun
Here is an example of cleanup.xml:
<cleanup> <repository> <url>http://localhost/PageBox/Repository/WebServices/Retry.asmx</url> <user>admin</user> <password>admin</password> </repository> <repository> <url>http://localhost/PageBox/Repository2/WebServices/Retry.asmx</url> <user>admin</user> <password>admin</password> </repository> </cleanup> |
For each Repository, cleanup.xml contains
The URL of its Retry Web Service
A user name and password of a valid administrator account on that Repository
The CleanupThread restores cleanup.xml on an ArrayList of RepositoryEntry.
At each loop, ThreadRun enumerates the ArrayList and calls for each Repository the Cleanup method of the Retry proxy.
error writes an error entry on the Application Event log with a RepoCleanup source.
log writes an information entry on the Application Event log with a RepoCleanup source if the logging mode, toLog is true.
Retry.cs is a SOAP proxy. It has been generated from the Retry Web service of the Repository using wsdl.exe. The constructor has been modified to set the Web service URL, which has to be the Repository URL.
ProjectInstaller.cs is a generated class responsible for the installation and de-installation of the Windows service.
In .NET beta 2, we must set the service user and password. Even in Release version, because RepoCleanup can invoke Retry on other machines, we should use a network-enabled account with write access to the registry.
To avoid hard coding the user and password, during installation and de-installation, ProjectInstaller prompts for the user name and password.
TestRepoCleanup was designed to test RepoCleanup functions.
Therefore it includes the same classes as RepoCleanup:
CleanupThread.cs
Retry.cs
You can use it to test your modifications.
It is also user-friendlier than regedit and the Windows service startup parameters to set the registry entries.
TestRepoCleanup uses a Windows form, TestCleanup.
The TestCleanup form contains two buttons, Start and Stop.
The TestCleanup class contains three methods:
The constructor that retrieves the cleanup.xml path and the logging mode from the registry. It also sets a text box and a check box accordingly
OnStart called when you click on the Start button. It retrieves the content of the text box and the check box, updates the registry and creates a CleanupThread and a worker thread where the ThreadRun method of CleanupThread will run
OnStop called when you click on the Stop button. It sets toStop and issues a pulse to gracefully terminate the worker thread
Contact:support@pagebox.net
©2001-2004 Alexis Grandemange.
Last modified
.