Category Archives: Dot Net

COM+ calling multiple .Net versions risks blowing the memory limit

From the Things I’ve Found That Might Affect Other People But There’s Not Much Detail In Google About It department

Not that I have much to add to the sum total of published knowledge on this, but our situation is we have a COM object (legacy code) calling .Net 2 objects (not-quite-as-old legacy code).

We’re upgrading it all to .Net 4.5, but the .Net stuff is an easier change, so we’ve been doing that first, naturally in a carefully planned, staged manner.

It turns out that COM+ objects have a 1 Gb memory limit.

And it appears that when you have them calling a mix of .Net 2 and .Net 4 objects, the overhead of being able to call two different .Net Framework versions becomes an issue.

At least that’s our theory based on what we’re seeing — looking at ProcessExplorer showed about a dozen assemblies loaded for each version of .Net.

One blog post I read suggested a 600-800 Mb overhead for each .Net version. I can’t confirm that, but certainly we’ve had more Out Of Memory exceptions than we expected.

We’ve resolved it by going back to our .Net 2 code (so only one version is held within the COM+ process at once), and we’ll do the big switch all at once. Hopefully that’ll resolve it.

The COM object will also be switched too of course, and once that’s done, running everything in .Net 4, plus a move from 32-bit to 64-bit machines, apparently will lift that 1 Gb limit to 8 Tb!

Cool!

How to do null dates in database queries in VB.Net

They do make you jump through some hoops, but I think I’ve got it worked out.

Dim dYourDateField As Nullable(Of Date)

…then you either set it to be a date (using DateSerial or CDate or whatever, or you set it to Nothing.

Then when you’re using it in a database query, the parameter can be set like this:

oCmd.Parameters.Add(“@YourDateField”, System.Data.OleDb.OleDbType.DBDate).Value = dYourDateField

That’s it. At least, it seems to work okay for me. Touch wood. Apparently it should be okay in the .Net Framework 2 onwards.

[Another in an occasional series of things Daniel posts about so he can easily re-discover it next time he needs to remember how it’s done.]

Please insert the Visual Studio .Net Prerequisites disk for visual studio.net

I’ve done this before, it should work: I’m running .NET on this box. I was installing .NET onto our build box here, and I kept banging my head up against step 1:

You have inserted the incorrect disk. Please insert the Visual Studio .NET Prerequisites disk for Visual Studio .NET

Hmmmm says I, it certainly seems to be labelled “Visual Studio .NET Prerequisites disk for Visual Studio .NET”. Oh, hang on, it says “Visual Studio .NET 2003 Prerequisites disk, Microsoft Visual Studio .NET Tools for the Microsoft Office System 2003”. Surely that’s the same thing? I’m installing off the “Visual Studio .NET 2003 Enterprise Architect” disk, they’re both yellow, this all seems right.

But it was not right. What I instead needed to do was grab the DVD that has all this stuff on it: it’s version includes the prerequisites right in the VS2003 install directory. Silly me. I should have known there were many versions of VS.NET. Some of them will install.

QueryInterface for interface xxx.yyy failed

My .NET web service – which wraps some legacy COM objects – wasn’t working. Development under VS2003 using .NET 1.1 worked fine in my dev environment, but in test env it just kept whinging:

InvalidCastException: QueryInterface for interface xxx.yyy failed

That’s a pretty basic failure – it couldn’t even obtain a xxx.yyy interface from the COM object. I figured it was a IIS security problem: a .NET desktop app using the same set of COM libraries worked fine.

The thing was, when I set the user account to operate annoymous web users under to local Administrator, it still didn’t help. Perhaps, I thought, this isn’t a permissions problem. Web users are now, after all, Gods.

Perhaps, Glen suggested, I was running .NET 2.0 and .NET 1.1 simultaneously?

No.

It turns out missing part was the

<identity impersonate="true" />

line out of the web.config file in the directory in which my webservice lived. Also, the lack of a web.config file in the directory in which my webservice lived caused a little bit of a problem. I didn’t realise that at the time, but found out that the impersonate setting can also go in one’s machine.config file also – but that has global implications. So I stepped back to putting it in my web service’s own web.config file.

Why does the Web Setup Project fail to include important little files, like my .asmx and web.config files? What is the point in having a wizard that just makes a installer that doesn’t install a working system? And the dependancies tree! God, just let me specify – or figure it out for yourself – the order in which to register the COM objects.

But guess what? All of that is unnecessary, if only your Installer derieved MyEventLogInstaller is set up thusly:

	[RunInstallerAttribute(true)]
	public class MyEventLogInstaller : Installer
	{
		private EventLogInstaller myEventLogInstaller;
		public MyEventLogInstaller()
		{
			//Create Instance of EventLogInstaller
			myEventLogInstaller = new EventLogInstaller();
			// Set the Source of Event Log, to be created.
			myEventLogInstaller.Source = "Josh's Web Service";
			// Set the Log that source is created in
			myEventLogInstaller.Log = "Application";
			// Add myEventLogInstaller to the Installers Collection.
			Installers.Add(myEventLogInstaller);
		}
	}


– with the RunInstallerAttribute being the super important part. Or perhaps it should read RunInstaller. But don’t worry, neither of them actually cause the installer to run them. As such, all you need do is issue the command

installutil "MyStupidWebService.dll"

after the installation program is done and you’ll be cooking with gas.

Simple, huh? No need for that nasty web.config file after all! Especially with it impersonating a dud security context.

Oh! And remember to issue a regsvr32 comcomponent.dll command also!

A dead giveaway that you haven’t run installutil is if you get an exception like this:

System.TypeInitializationException: The type initializer for "MyStupidWebService.Global" threw an exception. ---> 
System.InvalidOperationException: Cannot open log for source {0}. You may not have write access. ---> 
System.ComponentModel.Win32Exception: Access is denied
   --- End of inner exception stack trace ---
   at System.Diagnostics.EventLog.OpenForWrite()
   at System.Diagnostics.EventLog.WriteEvent(Int32 eventID, Int16 category, EventLogEntryType type, String[] strings, Byte[] rawData)
   at System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData)
   at System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType type, Int32 eventID, Int16 category)
   at System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType type, Int32 eventID)
   at System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType type)


because installutil will create an entry for Event Logging, if you’ve developed the appropriate installer. And because the person running installutil has decent privileges, it will actually work, as opposed to your web service trying to do it when it’s running in a securely locked down account.

C# module entry point

I’ve made a C# Web Service. Now I need a deployment project for my Web Service. After installing, it turns out that my Web Service needs to set the security on a registry key to allow the ASPNET user Full Control. Fine. I’ll need some sort of hand-written code to do that, because security is something the installer doesn’t cover. Stumbling around the help and web, I find I need to View | Editor | Custom Actions to create a Custom Action (right-click On the Install event/action, select Primary Output from JoshsPrimaryOutput; on the properties of this new Custom Action set InstallerClass to false and set EntryPoint to JoshsEntryPointFunction). Build.

I get the error:

Unspecified module entry point for custom action ‘<name>’ in JoshsPrimaryOutput.dll

Which the help… helpfully tells me to fix it I need to

…specify a valid entry point within the DLL.

Fine, makes sense. I’m not stoopid, I’ve been a C++/Windows programmer for a very long time. I know DLLs, I know entry points, this holds no fear for me. C# has DLLimport. It seems to be missing DLLexport. I’ve just spent several hours searching online help and the web for an answer, so now I turn to you, our esteemed readers.

How do I specify a module entry point in C#?

Calling COM from .Net, and vice versa

I’m working on a project that uses web services code written in .Net (‘cos it’s heaps easier that way) but calls legacy code written in VB6. And vice versa.

(Wow, I never thought I’d be referring to VB6 code as legacy, but there you go. None of your smart comments, any VB-haters out there.)

Here’s what I’ve discovered about making it work. Continue reading

Migrating .Net 1.x to 2.x

Having got Visual Studio 2005 into my hot little hands, I’ve upgraded one of my projects from VS 2003 to 2005, and .Net Framework 1 to 2. Just loading it into VS2005 seemed to do most of the work for me.

I did find the new VS gives out a few very informative warnings in the code editor, such as unused variables. Good stuff (and shame on me for being so sloppy during repeated revisions of code).

The other thing I found was a few things had changed in the Web.Config file format. After much fiddling I found it easier to create a fresh one and copy my custom settings into it, than try and convert the old one over.

The only catch is that after copying it all over to the test server, it didn’t work. Turns out apart from installing the .Net 2.X Framework on your server, you’ll also need to get into the IIS setup and make sure it knows it’s now a 2.X application.

Other than that, pretty smooth. The one gotcha on my actual code was a custom button click routine that took the form QueryString and stripped out all the ASP.Net guff I didn’t want needed a bit of tweaking, as in .Net 2.0 there’s an extra __EVENTVALIDATION value. (My version is adapted from a 15seconds.com article, and is used to produce tidy QueryStrings that can be bookmarked.)

.NET security bites back

I was running a .NET app, and all it did was say:

Request for the permission of type System.Security.Permissions.FileIOPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 failed.
Request for the permission of type System.Security.Permissions.FileIOPermission, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 failed.

After I hit Ok, the app crashed with an exception. I didn’t write it. Others could run it, I couldn’t. What was I doing wrong?

I was running the exe from a network share. Copying the exe to local fixed the problem.

Monday snippets

From the forthcoming book The Search: How Google and Its Rivals Rewrote the Rules of Business and Transformed Our Culture, here’s an article about how Google got started.

How to deploy Visual Studio .Net applications to Linux. (via Brad)

Now maybe I can sell off my old BBC B, once I get a Beeb emulator working. Shame I might never recover my old Ultima clone that some friends and I were working on in 1988.