Either if you migrate your application from VB6 to C# or if you develop a new application in C# something you end up with cases where you need to use your classes in legacy apps. Some of them could have been written in VB6 or could even be VBA macros in Excel applications.

Exposing your .NET classes can be sometimes very easy (you can think is just a matter of putting a ComVisible tag) but in other occasions is not that simple. Specially if your legacy application is using a lot of Late Bound calls like in VBA, so you must make sure that the COM information that you are exposing for your class is exactly what you really want and need.

OK. So I will provide some guidelines or some steps you should follow to provide a consistent COM interface for your .NET Code.

1. First you have to add the [ComVisible(true)] attribute. Don’t think that’s all. Even if in some cases that is enough is better if you take an strict control of want is being generated for your class. Ok Let’s use the following class as an example:

In this case your class will be expose using all defaults. That is, a progId that will be the <AssemblyName>.ClassName an interface _<ClassName> is generated and the class is exposed only for IDispatch, which would not provide class information if you add the tlb reference to a VB6 or VBA project.

And if you run this code in VB6 you will have a problem like type mismatch when you try to use the method x.CreateAClass because it is returning an object that is not exposed thru COM.

So my recommendation is to make explicit what you want to expose. Maybe you only need some of the methods to be exposed. Well that is step two.

2. Define a public, ComVisible(true) interface that will define the methods that you want to be exposed thru COM. Sometimes it is better to implement the interface explicitly. I even recommend using partial classes so you isolate the COM stuff from your normal class. If you class is very simple you can leave all COM stuff there.

//It is better to have an interface, because//you are completely sure what you are exposing or not
[ComVisible(true)]
public interface _MyVerySimpleClass
{
int GetMyLuckyNumber();
}

3. (Recommedation) This is not an obligatory step but I recommend using partial classes.

[ComVisible(true)] <—This is obvious because you want to use your class in COM

[ClassInterface(ClassInterfaceType.None)] <—This is because your want to take charge or what will be generated in your Typelib (tlb)

[ComDefaultInterface(typeof(_MyVerySimpleClass))] <—This is to indicate the interface that holds your COM visible methods.

[ProgId("InteropExamples.MyVerySimpleClass")] <—To establish which will be the progId not have a generated one [Guid("{029D468C-8BE6-498f-8A57-3B4B0306BA41}")] <—this is important specially if you are trying to accomplish binary compatibility

Optionally add this attribute [IDispatchImpl(IDispatchImplType.CompatibleImpl)] this is currently marked as an obsolete attribute but it still works and I have found scenarios, specially in some VBA applications where you need this attribute in order to make some late bound calls.

4. And Explicitly implement the interface methods. This is important because some of the return values or arguments might need convertions. For example what can you do if your method returns a DataSet and your Excel VBA script is expecting something like a Recordset (more on this on other posts).

So now you will have a class like:

//Using partial classes allow you to separate all the//COM plumbing and leave your .NET implementation simplepublicpartialclass MyVerySimpleClass
{
public Class2 CreateAClass()
{
returnnew Class2();
}
publicint GetMyLuckyNumber() { return 15; }
}
//It is better to have an interface, because//you are completely sure what you are exposing or not
[ComVisible(true)]
publicinterface _MyVerySimpleClass
{
int GetMyLuckyNumber();
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)] //This is to make sure that no automatic generation of COM methods is done
[ComDefaultInterface(typeof(_MyVerySimpleClass))] //This to explicitly establish which is the default interface
[ProgId("InteropExamples.MyVerySimpleClass")]
[Guid("{029D468C-8BE6-498f-8A57-3B4B0306BA41}")]
[IDispatchImpl(IDispatchImplType.CompatibleImpl)]
partialclass MyVerySimpleClass : _MyVerySimpleClass
{
#region _MyVerySimpleClass Members
//Explicit implementation is better because it avoids messing your .NET//class specification. Sometimes when you expose thru COM you can have problem with//methods overloads. For example you have to have the same method name but differente //return type. Or you have a collition with an existing member.int _MyVerySimpleClass.GetMyLuckyNumber()
{
return GetMyLuckyNumber();
}
#endregion
}

And your TLB is now explicit and exposes ONLY what you really really want.

Sometimes when you do a migration, you still need to “Interop” with legacy applications.

Normally this interop is done thru COM and .NET assemblies can be easily registered with COM. However the devil is in the details, and there are always subtle details that can be difficult to tackle with COM Interop.

One of those subtle details is that the tlbexp tool (this is the tool that generates the .tlb for a .NET assembly) generates a prefix for enum elements.

When you use this tlb for example in VB6 look at the member names for the enum:

If you want to be able to use your enum fields unchanged then this is the modified IDL you will have to use. The OLE2View Tool adds an extra “{“ to the IDL custom attribute and the enum name must be put after the enum keyword.

Save the modified .idl file as ClassLibrary1.dll and run a command like:

midl ClassLibrary1.idl /tlb ClassLibrary1_new.tlb

and then register the new tlb with:

regtlib ClassLibrary1_new.tlb

NOTE: I you cannot find the regtlib tool you can look for it at: %windir%\Microsoft.NET\Framework\v2.0.50727 it will be there with the name regtlibv12.zip. If you still cannot find it, download it from HERE

When a VB6 COM+ Component is migrated to a ServiceComponent, you might want to take advantage of the Configuration files of .NET to specify your connection strings and other important information.

So where should your App.Config go.

There is a slight diference with a ServiceComponent. Remember that for a ServicedComponent the hosting process is ‘dllhost.exe’. So your programs will look for config files in %windir%\System32, which is not a very nice solution.

You can instead set the ‘Application Base Directory’ of the COM+ Application.

Follow these steps:

1) Create an application.manifest file and copy it to the directory that will be used as the base directory for the COM+ application. The file can be like:

Today, as part of the Visual Studio 2010 launch, Microsoft published a video of my coworker, Esteban Brenes, doing a brief demo of the latest beta of the Visual Basic Upgrade Companion 4.0. In this video, version 4.0 of the VBUC is used to generate code that works correctly with Visual Studio 2010. This is part of the VSIP Partners CAN DO! series of videos, which can be seen in this link.

I am proud to announce that today ArtinSoft released version 4.0 Beta of its flagship product the Visual Basic Upgrade Companion.

This new release once more collects our learnings from migrating millions and millions of lines of code from Visual Basic 6 to VB.NET and C#.

This release revolves around a number of themes:

1) Visual Studio 2010 compatibility: You can now use the VBUC to create projects that are compatible with Visual Studio 2010.

2) Take advantage of new framework features: The code generated by the VBUC now takes advange of some advanced features of the .NET Framework to improve the quality of the code avoiding dependencies to any third party runtime.

3) Compatibility with Windows 7 and 64 bits system: The platform is evolving and the VBUC is evolving along with it. Now the VBUC is compatible with Win XP, Vista and 7 on both 32 and 64 bits systems.

4) Impoved usability: We are trying to minimize the learning curve to start a VB migration project. There will be even more changes in this theme for the next release. (I am specially excited about this!)

We are very happy to announce the Visual Basic Upgrade Companion 4.0 Beta. You can now download a trial from the Trial Request page. While we complete beta testing, we’ll have both version 3.0 (current release version) and the 4.0 Beta available for download. If you have the chance, we would really appreciate it if you could download the beta, and send us any feedback either through ArtinSoft’s regular support email (support@artinsoft.com) or through my blog Contact Form.

This new version contains a large number of improvements over version 3.0, including:

Increased productivity for migration projects, with features such as improved conversion of ByRef/ByVal parameters (specially when working with Windows APIs), TypeName/TypeOf support, improved default property conversion, generate code to explicitly release COM objects when required, and hundreds of smaller enhancements and bug fixes that greatly improve the conversion of VB6.0 code.

Improved the user experience by adding localization/internationalization for German and Japanese and completely redesigned the installation and license process. Installing a license is now a straightforward process (no more copying files!!), and it is now possible to install and execute the VBUC on both 32- and 64-bit versions of Windows Vista and Windows 7, as well as 32-bit Windows XP. The installation requirements were also greatly simplified, so you don’t need Visual Studio installed to install the VBUC (though it is still recommended). You can now also select the target version of Visual Studio to generate the appropriate Solution file (*.sln). The VBUC can generate Visual Studio Solutions for version 2005, 2008 and 2010.

Enhanced Grid migration, by mapping the Microsoft Flexgrid and APEX/ComponentOne TrueDBGrid to a grid that extends the native .NET DataGridView. It will no longer be required to purchase a third-party grid solution when moving from these grid to .NET if you wish to move to 100% native .NET code without using COM Interop.

Improved assessment capabilities, by improving the accuracy of the VBUC Assessment Mode and making additional changes so members without specific mappings are tagged with an EWIs – in the past only members that were explicitly tagged as “Not Mapped” had an EWI.

“If you utilize VBA macros in your work environment, they will no longer work unless the VBA module is installed on your system. “ “When you run a command that requires VBA, a message dialog box will be displayed stating that VBA is no longer installed with AutoCAD and directing you to a website where you can download the VBA module. “

And also you can see that Autodesk states: “Autodesk is evaluating how long VBA will be supported in Autodesk products in the future. Though supported in the AutoCAD 2010-based products, it may or may not be supported in future releases. Therefore, it is strongly recommended that VB developers develop all new code using VB .NET.”

VBA does not support 64bit systems in a native way.

But If you want some advice from the VB migration experts or help on your migration project from VBA to VB.NET or C# you can us contact Artinsoft Migration Services.

We build the VB Upgrade Wizard that shipped with Visual Studio and have been doing VB migrations for years.

In it March issue, Visual Studio Magazine published an in-depth article about legacy migrations called “Unlocking Legacy Code”. This article talks about the challenges faced by companies migrating from Visual Basic 6.0 to .NET, the drivers behind these migrations and the pros and cons of using an automated migration solution.

The article uses BEMAS Software as a case study for successful migration products. I am incredibly happy they are doing as well as they are with the conversion – they are using our tools, and I visited BEMAS about a year and a half ago to train them on the VBUC and help them plan the migration project. I remember they had a lot of conditional statements (by “a lot”, we are talking thousands of different combinations), as mentioned in the article:

"We also ran into some issues with the conversion tool because early on in the VB code we did a lot of #ifs, which means that the code acts differently depending on how you compile it," Pownall adds. BEMAS worked with ArtinSoft so that VBUC would recognize those instances and convert the code correctly.

It was quite a challenge to get it to convert, since the default behavior of the VBUC is to convert the code inside the conditional statement that evaluates to “TRUE”. Commenting out the conditionals wasn’t going to work either, since that would cause multiple variable declarations and other semantic errors that caused issues during the migration of this particular code. In the end we worked together with BEMAS, and with heavy involvement of the VBUC development team, we managed to modify the tool enough to get the code converted correctly.

Another very interesting item mentioned by Steve Pownall in the article, that I want to talk about some more, is the fact that even though the code came through very cleanly, it didn’t have the .NET architecture they were aiming for so they had to “The dev team had to massage or opted to rewrite the rest of the codebase manually in C# and .NET 3.5 using VS2008.”. This is a very important point, since the overall architecture of the code will remain as it was in VB6.0. The migration, however, gets you quickly to a stable .NET codebase that you can then rework to make it take advantage of the latest features of the .NET Framework. In our experience, this path (migrate, then enhance) is the one with the lowest risk, and it allows you to reduce the time to market for your applications by a wide margin. This is important to keep in mind, since we, as developers, always want to improve the code base – it is part of our professional formation, and I would say, part of our nature – but we sometimes fail to grasp the additional risk this implies. The migration is very controlled process, that gets you predictable results in a short time. Enhancing the application after the migration may seem like duplicating work (and indeed, there are enhancements that can be done during the migration process) but it guarantees that you will get a .NET in the allocated timeframe and budget, not to mention the cost advantage.

One very common requirement for migration projects is to adapt certain error handling patterns used in a customer’s Visual Basic 6.0 code to the structured error handling provided by .NET, cleaning up the code, improving its maintainability, and, whenever possible, complying with .NET best practices.

The VBUC already converts several commonly used error handling patterns, such as the ones described in this old post. There are, however, situations where the VBUC is not able to recognize a pattern. these usually involve Goto statements, On Error Resume Next, Resume Next or some other construct usually associated with “spaghetti code”. When one of these patterns is encountered, the VBUC does a very basic transformation and generates an EWI so it can be cleaned up through manual intervention later on, such as in the following example:

Most of the time it is possible to generate a solution that will correctly convert the error handling pattern, maintaining functional equivalence and meeting any additional coding guidelines from our customers. For the previous example, The VBUC can be customized so the generated code looks as follows:

This example makes some assumptions on the nature of the code and on the intention of the original VB6.0 developer, in particular:

Errors raised by <STATEMENTS 1> should be handled by <STATEMENTS 5>

Errors raised by <STATEMENTS 2> should be handled by <STATEMENTS 4>

<STATEMENTS 3> is cleanup code that should always be executed

The Exception needs to be thrown again without loosing any information

This is just an example, but the intention is to show what type of customizations can be done. The VBUC transformation engine is very powerful, and, as long as a pattern can be identified, can help you automate the solution to most VB6.0 problems.

The LINC/EAE migration tool can automatically generate reports that can be used to extract your data from DMSII to your target database, for example Oracle. In this scenarios the Oracle SQL Loader tool is used. However you might problems loading the data because the string values can contain the same characters you are using to enclose them.

How can you “escape” the enclosing characters. Well I found the answer in another forum:

If two delimiter characters are encountered next to each other, a single occurrence of the delimiter character is used in the data value. For example, 'DON''T' is stored as DON'T. However, if the field consists of just two delimiter characters, its value is null.

Back when it was first announced I made a couple of posts about Windows 7 XP Mode (available here and here). Now that I’ve been using almost every day for the past few months, I wanted to revisit the topic and write about my hands-on impressions. In this post I’ll show how applications that run under XP Mode integrate with the regular Windows 7 environment.

The integration features of XP Mode work really well, for the most part. Applications installed in the Virtual Machine appear right there on the Start Menu:

Linc\EAE used profiles for their queries. Well the profile information is used by our migration tool to generate indexes. In Java is easy to intercept all SQL statements used by the translated application and analyze them.

To analyse how a query is executed you have to study its explain plan. For go here an excellent guide on EXPLAIN PLAN.

After you read that page, you will find useful the following function, that will shorten the lines that you have to type to see the explain plan:

When we migrate from LINC/EAE to Oracle, the migration tool generates an schema an tables form the original ISPECS. I came across with the problem that I had been playing around with a test database and I didn’t know who was the owner of the table.

As I developer I usually receive emails with .zip attachments and .xml attachments. When I’m looking for an old email I hate that I have to open the attachment just to see if it has the files I’m looking.

Why isn’t there a built-in preview functionality for .xml and .ZIP files?

A while ago I wrote about the decision that many people face when
starting to consider a migration from Visual Basic 6.0 to the .NET
platform: choosing the target language, mainly between VB.NET and C#. Today I found a great post by John Fuex
on that subject, not inciting the war between both trenches but instead
describing the process he and his company went through to solve the C# versus .NET dilemma.
He basically used the following criteria to qualify each language:
Functionality, Learning Curve, Existing Code, Developer Preferences,
“Street Cred” (for both the developers and products), and Recruiting.
But in the end it reinforces the notion that there’s not a standard
solution, so the selection should always be made case by case.