How to workaround slow down in loading chm file into C# .NET program from background security software

Hi experts
My C# .NET program has two panels. One panel displays UI User Controls. The other panel (Help panel) displays help text that was kept in a separate chm file.

How it works is whenever user hovers the mouse over an UI User Control, an internal tag string was generated in order to navigate to some location within the chm file for the corresponding Help text. This help text is then displayed in the Help panel.

It had been fine until recently a new security software was installed. The security software would kick off every single time inadventently to examine the newly loaded chm file when user hovers the mouse to different UI Controls. This slows down my program a lot, and makes it almost unusable.

My program uses the .NET library 'WebBrowser.Navigate(.)' in order to navigate for information kept in a separate chm file. To my understanding, the method 'WebBrowser.Navigate(.)' was defined as:
Loads the document at the specified Uniform Resource Locator (URL) into the System.Windows.Forms.WebBrowser control, replacing the previous document.

I am thinking if there is any way I could avoid loading the document every time while navigating to a different location within the chm document.

Who is Participating?
No hand coding.  You extract the thousands of text strings and their associated control names/IDs and automate the incorporation of the text into your application.
I recommend you in this case use a different technique. At the form load time load the contents of your chm file into memory. Then, use WebBrowser.DocumentText or WebBrowser.DocumentStream property to set the text of the WebBrowser to the required section of the chm document.
dominicwongAuthor Commented:
Thanks chaau for your help.
Hope you don't mind, I am afraid I need some more direction from you.

>> load the contents of your chm file into memory
Did you mean calling the 'WebBrowser.Navigate(.)' method and keep the content in the 'WebBrowser.Document'.

>>  use WebBrowser.DocumentText or WebBrowser.DocumentStream property to set the
>>  text of the WebBrowser to the required section of the chm document
Could you tell me how to do this or point me to some reference on how I might do it.

Thank you very much.
The Firewall Audit Checklist

Preparing for a firewall audit today is almost impossible.
AlgoSec, together with some of the largest global organizations and auditors, has created a checklist to follow when preparing for your firewall audit. Simplify risk mitigation while staying compliant all of the time!

btanExec ConsultantCommented:
for the code wise, may want to consider async/wait pattern - some sort of "DoNavigationAsync" (can try google for example if any similar scheme) that executes asynchronously (and checking for WebBrowserReadyState.Complete") or some "WaitingFor" function to check for delay on Navigate completion. in short, you want WebBrowser.navigate to be asynchrounous, so you need to setup an event handler to handle the navigation completed event

actually if the chm is not going to change or is the same chm most of the time then maybe we can disable the security scanning - maybe there is some exception rule for the security scanning to avoid (just like some system or page file that it is not scan as CPU resource is too huge - the scan is done probably in off peak user hr).

will also be good if the security scan can be called via API if that is available for the security s/w. at least that can give you the API to decide if scan can be enabled. I was thinking of checking if chm is changed via some hash check - meaning generate a hashed string which is based on MD5 or SHA1 or some simple checksum to ascertain its original state - then decide the scan. However, this hashing will need to be maintained in some config and done before hand also it may not be any faster esp if the chm is huge (hashing req loading whole file as well), unless there is some signature we can use as "hash" to determine chm is in good state.
I think there are a couple of ways to work around this.  Both involve mining the chm file for all the help text.
Classic approach:
1. get the contents ahead of time, during development, for all controls.
2. use OnHover event to display the text.

CSS approach:
.HoverText {
  visibility: hidden;
  opacity: 0;
.input:hover .HoverText {
  visibility: visible;
  opacity: 1;

<p class="HoverText">This is text about a control from the chm file</p>
You could also transfer all the mined hover text into your database, replacing the real-time mining of the chm file with database calls.

You could also include the hover text in the content of the web page as a JSON object and use javascript to render the hover text from the local content.  Be aware this approach may cause page bloat.
btanExec ConsultantCommented:
Probably this can be useful thought using HelpNavigator and HelpKeyword

Choose an appropriate HelpNavigator Enum value so that the desired section of the help file will be opened and queried using your HelpKeyword value. The latter should hold a context-specific keyword that you had included in the Help file before compilation. It could be an index entry, a search value or the name of a file that is part of the compilation.

It would be interesting to know that when you invoke a web page (whether local or remote) using the Help.ShowHelp method, you are opening your browser window in an external process. This means that when your client application process dies, the browser process holds its ground unless you had earlier closed it yourself. It can be embarrassing if your Help file hangs around after the application that called it has shut down. However, it does not happen with .chm files that are opened with the HelpProvider component.

As a work around, I suppose we could use an instance of the Process class found in the System.Diagnostics namespace.
dominicwongAuthor Commented:
Thanks btan and akimark for your help and directions.

In reply to btan:
>> "... DoNavigationAsync..."
The help paragraph that shows up in the help panel (located at the bottom of the program) is meant to give immediate information to user about the intention associated with the UI control when they hover it. Therefore, navigating async will frustrate a user.

>>  " .. disable the security scanning..."
This is not possible in my case as the software is meant for external customers, and we have no prior knowledge what kind of security s/w they use.

>> "...using HelpNavigator and HelpKeyword.."
What happened is my program has been working until recently the security s/w is replaced, then I realize that some security s/w can be a problem. Therefore, I am hoping not to rewrite the existing code.

In reply to akimark:
>> "...get the contents ahead of time, during development, for all controls.."
There're thousands of Controls and each has its own help text. Things continue to change. So getting the contents during development, which I think you meant hard coding, is not possible.

Ideally, as per the suggestion from the first expert chaau, preloading the chm content into memory, and access it during run-time is the ideal solution in my case as I can keep the existing architecture and don't need to rewrite much. Unfortunately, I don't know how to do it and I am seeking more directions on this approach. I would appreciate if either of you could fill me in on how to do that. Thanks in advance.
btanExec ConsultantCommented:
A CHM file contains its own file system. You can handle read/write streaming using the IStorage interface, which supports the creation and management of structured storage objects. Loading into the memory will also be an one time slow process and subsequently it will be via the memory access - security scan will still be enforced too. Nonetheless, below is a HTMLhelper lib which you may be interested ... (esp on the "The data dumping" section). Note that this is kind of old archive and istorage seems to be deprecated.

I guess we are looking at memory mapped file with more MSDN info below - main thing is to map view for specific access but note scanning may still be existence and whether it is fast based on various security s/w can differs as well...

maybe eventually it is offline check of file or exception if that is alright....
btanExec ConsultantCommented:
performance and security need to balance out as far as I see, whether indexing, memory mapped or stream reading will definitely have some impact (even with caching) - probably is to review whether is place to really need help friendly and if chm alternative can be consider instead - meaning not a file based or some sort of online or text readme ... or just some tooltips
dominicwongAuthor Commented:
Thanks aikimark and btan.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.