Using SSL during a certificate request

If you need to request a certificate to use for a website, you need to generate a certificate request resulting in a certreq.txt you need for buying the actual certificate. Once the certreq.txt is generated, you can not use another certificate for your website because your request is still pending. The below figure shows the dialog you’ll see when trying to setup secure connections for a website for which a certificate request is pending:

request-pending

request-pending

There can be days, even weeks between the actual request for buying a certificate and the moment it is delivered, which voids SSL-communications for your website. To avoid this, you can create a new website, then use a development certificate and use that for your site until your actual certificate is delivered.

Creating a temporary website

Creating a temporary website

If your actual certificate is delivered, you need to delete your temporary website and you can use the actual certificate.

Posted in Certificate, MVC4 | Leave a comment

Intergraph issues database will be public available

Intergraph has an internal database for keeping track of all kinds of software issues, if you file a Trouble- or Change Request, it will end up in this database. This database will become public available in the 3rd quarter of 2013 according to Intergraph sources at Hexagon 2013. Also, if a problem gets fixed, the solution will be described so you know if applies to you. All this information will be public accessible and indexed by Google, so if you are facing a problem in G/Technology (or any other Intergraph product) google will find it and it will show up in the results of your search.

Posted in G/Technology, Intergraph | Leave a comment

Netviewer extensions

It doesn’t take much to create a Netviewer extension:

  1. Derive a class from Microsoft.Practices.CompositeUI.ModuleInit
  2. Create a constructor with a [ServiceDependency()] WorkItem argument
  3. Modify your ProfileCatatalog.xml

The class would look like this:

namespace NetviewerLibrary
{
	#region -- Using directives --
	using System;
	using System.Reflection;
	using Microsoft.Practices.CompositeUI;
	using d = System.Diagnostics.Debug;
	#endregion

	public class Init: ModuleInit
	{
	    public Init([ ServiceDependency()] WorkItem rootWorkItem)
	    {
		   d.WriteLine( "Init");
	    }
	}
}

This code is using a pattern from the Microsoft Enterprise Library version 2.0 (no longer supported by Microsoft) for setting up an external library to be invoked by an application. The external library in this case is your extension, the application is Netviewer. All it takes for Netviewer to invoke the extension is a class derived from Microsoft.Practices.CompositeUI.ModuleInit and create a constructor with an Microsoft.Practices.CompositeUI.ServiceDependency argument. In line 10 a Microsoft.Practices.CompositeUI.ModuleInit-derived class is declared and at line 12 you can see the constructor. If your extension is compiled to an assembly called ‘NetviewerLibrary1′, you include your extension in the ProfileCatalog.xml file and add your command to IngrViewer.exe.config, Netviewer will invoke your extension.

This is the ProfileCatalog.xml :

<SolutionProfile xmlns="http://schemas.microsoft.com/pag/cab-profile/2.0">
  <Section Name="Apps">
    <Modules>
      <ModuleInfo AssemblyFile="GTechnology" />
      <ModuleInfo AssemblyFile="NetviewerCommand.dll" />
    </Modules>
  </Section>
</SolutionProfile>

This is not very useful other then illustrating what it takes for Netviewer to invoke your extension. Netviewer works with commands, and each extension can have one more or of it. The ProfileCatalog.xml is where you define your extensions, the IngrViewer.exe.config is where you define your commands. In order to do something useful, we need to add our command to IngrViewer.exe.config and extend our code with a command handler:

This is the line in IngrViewer.exe.config which adds the command:

<command name="NetviewerCommand1" autocreate="true" tooltip="NetviewerCommand1" label="CustomCommand1" />

This is the code:

namespace NetviewerLibrary
{
  #region -- Using directives --
  using System;
  using System.Reflection;
  using Microsoft.Practices.CompositeUI;
  using Microsoft.Practices.CompositeUI.Commands;
  using Intergraph.OneMobile.Infrastructure.Interface;
  using d = System.Diagnostics.Debug;
  #endregion

	public class Init: ModuleInit
	{
		public WorkItem WorkItem{   get; set;   }

		public Init([ ServiceDependency()] WorkItem rootWorkItem)
		{
			d.WriteLine( "Init");
			this.WorkItem = rootWorkItem;
		}

		public override void Load()
		{
			d.WriteLine( "Load");

			base.Load();

			ControlledWorkItem workItem = this.WorkItem.WorkItems.AddNew();
			workItem.Controller.Run();
		}
	}

	public partial class MyController :
		Intergraph.OneMobile.Infrastructure.Interface.WorkItemController
	{
		[ CommandHandler( "NetviewerCommand1")]
		public void MyCommand_Handler( object sender, EventArgs eventArgs)
		{
			d.WriteLine( "MyCommand_Handler");
		}
	}
}

If you now run Netviewer, there will be an extra button with a label “NetviewerCommand1″ and if you click it, your commandhandler will be invoked.

Netviewer command

Netviewer command

Now let’s turn this extension in something useful, for instance placing a pinpoint. We want our command to ask the user to click in the Window and then place a pinpoint at the cursur. To do so, we need to extend our code with the following:

  1. A reference to the Netviewer MapviewService instance for setting up eventhandlers
  2. A Commandhandler for a left-mouse click
  3. Infrastructure code

The modified code looks like this:

namespace NetviewerLibrary
{
  #region -- Using directives --
  using System;
  using System.Reflection;
  using Microsoft.Practices.CompositeUI;
  using Microsoft.Practices.CompositeUI.Commands;
  using Microsoft.Practices.CompositeUI.EventBroker;
  using Intergraph.OneMobile.Infrastructure.Interface;
  using Intergraph.OneMobile.Map.Interface.Constants;
  using Intergraph.OneMobile.Map.Services;
  using Intergraph.Controls.oneViewer;
  using d = System.Diagnostics.Debug;
  #endregion

  public static class Global
  {
    public static int CallCount {   get; set;   }
  }

 public class Init: ModuleInit
 {
    public WorkItem WorkItem      {   get; set;   }

      public Init([ ServiceDependency()] WorkItem rootWorkItem)
      {
        d.WriteLine( string.Format( "{0}.{1} ({2}):{3}", GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name, Global.CallCount++, string.Empty));

        this.WorkItem = rootWorkItem;
      }

      public override void Load()
      {
        d.WriteLine( string.Format( "{0}.{1} ({2}):{3}", GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name, Global.CallCount++, string.Empty));

        base.Load();

        ControlledWorkItem workItem = this.WorkItem.WorkItems.AddNew();
        workItem.Controller.Run();
      }
  }

  public partial class MyController :
    Intergraph.OneMobile.Infrastructure.Interface.WorkItemController
  {
    #region -- Properties --
    public IMapViewService  MapviewService    {   get; set; }
    public string      OldMapLocateMode  {   get; set; }
    #endregion

    [ CommandHandler( "NetviewerCommand1")]
    public void MyCommand_Handler( object sender, EventArgs eventArgs)
    {
      d.WriteLine( string.Format( "{0}.{1} ({2}):{3}", GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name, Global.CallCount++, string.Empty));

      this.MapviewService.SetStatusBar( "Click to place pinpoint");

      SwitchMapMode  ( );
      SetupEventSink  ( );
    }

    [ EventSubscription( EventTopicNames.MapViewLoaded)]
    public void MapViewLoaded_Handler( object sender, EventArgs eventArgs)
    {
        d.WriteLine( string.Format( "{0}.{1} ({2}):{3}", GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name, Global.CallCount++, string.Empty));

        this.MapviewService = WorkItem.Services.Get();
    }

    private void SwitchMapMode( )
    {
      d.WriteLine( string.Format( "{0}.{1} ({2}):{3}", GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name, Global.CallCount++, string.Empty));

      this.OldMapLocateMode = this.MapviewService.GetMapMode( );
      this.MapviewService.SetMapMode( Intergraph.Controls.oneViewer.MapModes.Custom);
    }

    private void SetupEventSink( )
    {
      d.WriteLine( string.Format( "{0}.{1} ({2}):{3}", GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name, Global.CallCount++, string.Empty));

      this.MapviewService.RedlineLButtonDown    += new Intergraph.Controls.oneViewer.RedlineButtonEventHandler( MapviewService_RedlineLButtonDown );
    }

    void MapviewService_RedlineLButtonDown( object sender, Intergraph.Controls.oneViewer.RedlineButtonEventArgs e )
    {
      d.WriteLine( string.Format( "{0}.{1} ({2}):{3}", GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name, Global.CallCount++, string.Empty));

      string  point    = string.Format( "{0}, {1}", e.XWorldPos, e.YWorldPos);
      string  pointType  = "UOR";
      string  fontName  = "G_MapPins";
      short  fontSize  = 24;
      string  fontColor  = "FF0000"; // --- Red
      string  charValue  = "F";    // --- Solid filled push pin

      this.MapviewService.PlaceLocationPinAtPoint(
                    point,
                    pointType,
                    fontName,
                    fontSize,
                    fontColor,
                    charValue,
                    "POI");
      StopCommand( );
    }

    private void StopCommand()
    {
      d.WriteLine( string.Format( "{0}.{1} ({2}):{3}", GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name, Global.CallCount++, string.Empty));

      RestoreMapMode  ( );
      ReleaseEventSink( );

      this.MapviewService.SetStatusBar( string.Empty);
   }

    private void RestoreMapMode( )
    {
      d.WriteLine( string.Format( "{0}.{1} ({2}):{3}", GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name, Global.CallCount++, string.Empty));

      this.MapviewService.SetMapMode( this.OldMapLocateMode);
    }

    private void ReleaseEventSink( )
    {
      d.WriteLine( string.Format( "{0}.{1} ({2}):{3}", GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name, Global.CallCount++, string.Empty));

      this.MapviewService.RedlineLButtonDown -= new Intergraph.Controls.oneViewer.RedlineButtonEventHandler( MapviewService_RedlineLButtonDown );
    }
  }
}

After running this command, a pinpoint is placed to indicate some point of interest :

pinpoint

pinpoint

You can download the complete source for this example over here.

Posted in Netviewer, Visual Studio | Tagged , , , | 6 Comments

Deploying an MVC4 Web application to Windows 2003

I had a hard time deploying an MVC4 application to Windows server 2003, so I thought I’d share my experience with you.

When deploying an MVC4-based website to Windows Server 2003, it is important to add Wildcard maps in Internet Information Services (IIS). The default IIS-configuration is based on extensions coupled to ISAPI-addins, but MVC doesn’t work with extensions so you need to tell IIS to have a ‘catch-it all’ extension. Here are the steps necessary to do so.

The target framework needs to be 4.0

If you develop a MVC4 website using Visual Studio 2012, the default .NET framework is 4.5. Windows 2003 doesn’t support the .NET framework 4.5 as you can read over here, so you need to downgrade the target framework to 4.0. You can easily do this with Visual Studio 2012 by changing the target framework in your project properties pages :

Target framework Visual Studio 2012 project

Target framework Visual Studio 2012 project

Installing the .Net 4 framework

The next step is to install the .NET framework 4.0. This comes in two flavours, the .NET 4 Framework Client Profile and the .NET 4 Framework which is the full framework. If you are deploying webapplications, you need the full framework, the Client Profile is a subset of the framework for desktop applications. You can read more about the differences over here. You can download the full redistributable of the .Net framework 4.0 at microsoft. After you installed the .NET 4.0 framework, you’ll see the following listing in installed programs :

.NET 4 framework installed

.NET 4 framework installed

The .NET 4 Framework Client Profile is the subset of the framework, the .NET 4 Framework Client Extended is the remainder making the full framework to be installed.

Configuring IIS to use .Net 4

After .NET 4 is installed, it is registered to IIS as an Web Service Extension, but it is not enabled by default:

ASP.Net 4.0 prohibited

ASP.Net 4.0 prohibited

Right click the ASP.Net v4.0.30319 line and select Allowed. After that, you should see the following screen :

ASP.Net 4.0 allowed

ASP.Net 4.0 allowed

Adding a Wildcard map

If you are deploying Web-Forms applications, then your done and your application should run. If you are working on MVC applications there’s one last step to do, you need to add a Wildcard map for your application. Go to IIS, select your project and choose Properties→Virtual Directory→Configuration and you’ll see the Application Configuration screen. In the lower part you can see a listing of installed wild card application maps, which is empty. You can add one by selecting the ‘Insert’ button:

Insert wildcard IIS map Virtual Directory

Insert wildcard map IIS Virtual Directory


The ‘Add/Edit Application Extension Mapping’ dialog shows up. In the Executable-text field, enter the path to the .NET Framework 4.0 isapi-extension which is normally c:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll. Be sure to unselect the ‘Verify that file exist’-checkbox :

Add IIS wildcard

Add IIS wildcard


Choose ‘OK’ and close the screen. Your dialog should now look like this :

IIS Wildcard added

IIS Wildcard added


Close the screen, and your MVC4 application should now be ready to run!

Posted in MVC4, Visual Studio 2012, Windows 2003 | Tagged , , | Leave a comment

Increasing G/Netviewer performance

Note: The monitoring and tests are done on G/Netviewer 9.4 environment. But I think it is also applicable for version 10.

After some in-depth monitoring of our G/Netviewer webserver for some days/weeks. We found a performance enhancement for G/Netviewer webserver. Our server has 4 cores and 8GB memory. On our environment there are 25 to 30 concurrent users working with G/Netviewer. When we measured the CPU time in the working hours, the statistics shown that the average CPU time was round 35% and users are complaining about performance. When we monitored the server, there are on average 5 mapserver.exe running and we specified that there can be 10 maximum, but it never reaches 10.

Also our statistics show there is almost no paralleled processing of the mapserver.exe. The data shows that mapservers are randomly fired after the other process is done. Mapserver1 processing something, then mapserver2, then mapserver1 again, then mapserver3, etc.  You should expect when there are 4 mapservers.exe, those executables will fire all at once if 4 users doing a Zoom-action within G/Netviewer, but it doesn’t. Sometime we do see that 2 mapserver.exe do simultaneously fire. Or when a extra new mapserver.exe is starting then it will process the modificationlog table in parallel processing. So the server can upscale to 10 mapservers and we would expect 80% CPU time, but that is not what happening.

In our environment we do have two G/Netviewer groups (Database users) specified in the G3E_loginmapping table. (In G/Tech 10 this table is not used anymore and everything is stored in IAM database) A quarter of the total users is specified in the g3e_loginmapping table and are mapped to an advanced usergroup. All other users are mapped to default usergroup. So we have only two usergroups and two mapserver.exe processing parallel….hmm. What if we created more usergroups, would G/Netviewer do more parallel processing. The answer is YES.

The G/Netviewer webserver processing does work like a supermarket. The GNWebMgr.exe is the store manager, Mapserver.exe is a checkout lane and the a netviewer group is the cashier. In our situation we had only two cashiers working on two lanes. When the shop got more busier, the queue are getting larger and the manager opens another lane. But there are no extra cashiers, so the cashiers need to switch between lanes.  When you define more groups in the g3e_loginmapping table you get more cashiers, so more parallel processing.

What you have to do is specify all frequent users in the g3e_loginmapping table and map those users to different groups. In the webcc.web_user table you van get information which users are logged in. But every time they login the Last_license_access date will be overwritten. So you can monitor this for example once per day, for one/two weeks. To get most frequent users and divide them over different groups.

Posted in Netviewer | Tagged , , , , | 2 Comments