Archive

Posts Tagged ‘c#’

CrossRef++ (A Microsoft Word Add-in)

March 11th, 2011 Angus Macdonald 3 comments

This is a Word 2010 that replaces Word’s in-built ‘add cross-reference’ tool. Why? — because it has annoyed me greatly whilst writing my thesis!

Installer (EXE Version).

Source code as ZIP, on Github.

Please note that this only works in Word 2010, not on any earlier versions.

Why this is ‘needed’

The standard word tool (pictured below) quickly becomes tedious to use in large documents for a number of reasons:

  • You have to switch between references for things (like figures and numbered items) constantly, and you have to use a drop-down box to do this.
  • It doesn’t remember your last referenced item, so if you’re constantly referencing a figure that is two pages down the list, you constantly have to scroll down to that reference.
  • It doesn’t remember the size of your reference box, so even if you have a massive monitor, you can only ever use a tiny fraction of it to search for references.

The Standard Word Cross-reference Tool

What CrossRef++ Does Differently

  • References are displayed in a task pane, which typically stretches the length of a screen, but can be moved around as well.
  • It remembers (roughly) where your last used reference was for each type (figure, numbered item, etc.), so you don’t have to scroll as much as before.
  • It provides a few big buttons to at the top to change reference type, which makes it quicker to change.

The CrossRef++ Tool

What it Doesn’t Yet Do

  • It doesn’t support all types of references (for endnotes and other things you need to use the old tool).
  • It doesn’t handle re-sizing the task pane well.
  • It doesn’t allow you to search through references, though I’d like to do that eventually.
Categories: Side Projects Tags: , ,

Using Windows Management Instrumentation in .NET

January 7th, 2009 Angus Macdonald No comments

A few weeks ago I posted an article about performance counters in .NET, which discussed how to get measurements on things such as CPU and memory utilization. Perhaps the biggest limitation of this class is the inability to get static information about the machine on which the program is running. For example, what if you want to find out how many processors a machine has, and the speed of each? Or if you need to get the IP address associated with a network interface?

Windows Management Instrumentation comprises a set of classes which allow you to query the system on anything from processors, to printers, to keyboard drivers. Essentially everything installed on the system can be queried as long as you know the correct command. This post provides some examples of WMI being used and links to the relevant MSDN sources which state what can be obtained in full.

Note: For the following examples to work make sure you import System.Management in your Visual Studio project. It is already included in the example project.

MAKING A QUERY

In WMI all results are accesed through SQL-like queries. For example, to find how much phsyical memory a computer has a query object is created, as follows:

ObjectQuery objectQuery = new ObjectQuery("select * from Win32_PhysicalMemory");

For a list of the attributes that can be selected from this look here.

Now we have a query object we can execute a query using ManagementObjectSearcher:

ManagementObjectSearcher searcher = new ManagementObjectSearcher(objectQuery);
ManagementObjectCollection vals = searcher.Get();

You can iterate over this collection as you would any other. The following code just prints out the amount of phyiscal memory on each piece of memory.

foreach (ManagementObject val in vals) {
Console.WriteLine(System.Convert.ToInt64(val.GetPropertyValue("Capacity")));
}

The ManagementObject has a number of properties (listed on the MSDN page) which can be retrieved. In this example the conversion to an integer value is completely unnecessary, but I’ve left it in because it becomes important when storing the value, rather than just printing it out.

val.GetPropertyValue("Capacity") can also be written as val["Capacity"].

WHAT QUERIES ARE POSSIBLE?

To see what classes can be queried have a look at the left of this MSDN page. Any part of the local configuration can be queried, making WMI a very powerful tool. However none of this is particularly efficient – you’ll notice a delay when executing some queries, so make sure you only do what’s necessary and cache the results.

EXAMPLE PROGRAM

Click on the following link for an example Visual Studio 2008 project performing some basic WMI queries and iterating over the results.

Example Project Source

If you’re looking for more dynamic results (such as CPU Utilization) I’d recommend looking at my post on Performance Counters.

Word 2010 Add-in: Word Frequency Counter

November 27th, 2008 Angus Macdonald 38 comments

I created this add-in to count the occurrences of each word in a given Word 2007/2010 document and then either display the result within Word, or save it to a CSV file. Both the executable and the source are available below.

Word Frequency Counter EXE (for Word 2010)

Word Frequency Counter EXE (for Word 2007) – Without Ignore List

Word Frequency Counter SRC (for Word 2010)

(These files seem to be a lot larger because of some additional dependencies that have been created. If you don’t care about the ignore list feature, the old files are listed at the bottom of this post.)

For the Technically Minded

The add-in is written in C# using Visual Studio 2008. Among the things I find interesting about the solution are:

  • The use of LINQ to sort the dictionary (a hashmap) which stores the words (key) and count (value) by value, rather than using an complicated comparable code. I discovered this here, and was suitably impressed.
  • The use of BackgroundWorker to multi-thread the computation of the results, and to relay the progress of this computation back to the interface. This example is fairly good.

The add-in also does the following things (in case, like me, you’re struggling to find how to do something in VSTO):

  • Retrieves all the words (tokens, more specifically) in a given word document and loops through them
  • Creates and populates a custom task pane
  • Adds some buttons to the Office 2007 ribbon in the review tab
  • Saves a string to a file, with the location specified by the use

Hopefully this helps you in some form!

Update (25/09/2010): Updated for Word 2010 with an ignore list feature added.

Update (17/11/10): Someone at online-tech-tips has written a good overview of the add-in here.

Update (20/11/2010): Updated with a basic in-built set of ignored characters including bullet points, dashes, and quotes. Also the ability to ignore numbers.

Update (27/03/11): Another write-up of the add-in here.

Categories: Side Projects, Work Tags: , , , ,

.NET Performance Counters

November 14th, 2008 Angus Macdonald No comments

This post discusses .NET Performance counters and their use in monitoring resource utilization.

.NET provides various classes for monitoring the resource utilization of the CPU, memory, disk and network cards. Sadly, the documentation is particularly vague with respect to what can be monitored and how this can be done. This article describes basic use of performance counters and gives a sample class (see end of text) which displays some of these on the command line.

PERFORMANCE COUNTERS
The PerformanceCounter class is used as the basis for all monitoring. This can be set up as follows:
private PerformanceCounter pcounter = new PerformanceCounter(categoryName, counterName, instanceName);

This constructor takes three parameters:

  • categoryName refers to the type of resource to be monitored. The following values are permissible on all machines (you can also create your own custom counters):
    • Processor
    • System
    • Thread
    • Memory
    • LogicalDisk / PhysicalDisk
    • Network Interface
  • counterName is the name of a specific counter within that category. For example, if monitoring the processor % Processor Time specifies that we want to look at the percentage of time the processor was busy during the sample period. The following pages list counters for each of the resources provided by Microsoft:
  • InstanceName specifies the instance of the resource being monitored. For example, when monitoring disk utilization you may want to specify which drive is to be monitored. Alternatively, to monitor all instances just enter _Total.

SOME EXAMPLES

private PerformanceCounter processorcounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");

Measures the percentage of time the processor was busy during the sample period.

private PerformanceCounter memcounter = new PerformanceCounter("Memory", "Available MBytes");

Shows the amount of physical memory available to the processor (in megabytes).

private PerformanceCounter diskcounter = new PerformanceCounter("LogicalDisk", "% Free Space", "_Total");

Shows the percentage of free disk space (over all logical disks).

private PerformanceCounter bandwidthcounter = new PerformanceCounter("Network Interface", "Current Bandwidth", "Intel[R] 82562V-2 10_100 Network Connection");

An estimate of the current bandwidth of the network interface. The instanceName in this case must be the name of the network card being monitored.

If you don’t know the name of your network card the following code may be helpful. It returns a string array of all the network cards on your local machine:

PerformanceCounterCategory category = new PerformanceCounterCategory("Network Interface");
String[] instancename = category.GetInstanceNames();

The same method can be used to find the names of logical disks or other devices on the local machine – just replace the Network Interface string with the category of your choice.

OBTAINING MEASUREMENTS
Now that we’ve instantiated our monitors we need some method of obtaining samples. For example, the following code extracts a sample from our processor counter:

float sample = processorcounter.NextValue();

There are a number of other fields and methods that may be of interest. To get a human readable description of the counter being used use the CounterHelp field:

String counter_description = processorcounter.CounterHelp;

FURTHER READING
This article covers the basics of the PerformanceCounter class. To see it used in practise check out some of these examples:

EXAMPLE PROJECT

Performance Counter Examples

Categories: Work Tags: , ,