PowerBuilder Migration

6. September 2006 05:48 by Mrojas in General  //  Tags:   //   Comments (0)
Powerbuilder is a nice language but is little propietary and the developer comunitty is not as big as the .NET or Java ones. It imposes some risks on Powerbuilder projects.
That why some shops have started moving some of their inhouse applications to other platforms.
Personally I feel that .NET is the more natural platform for migration. Even more there is now a datawindows.NET component. DataWindows are the core of any Powerbuilder application and using this component really makes it easier to migrate a PB application.
In my following post I will describe examples using the Datawindows.NET component to migrate some PB samples.
For more info on DataWindows.NET

Intellisense in VS

22. August 2006 06:53 by Mrojas in General  //  Tags:   //   Comments (0)

If you would like to edit XML files in Visual Studio and use intellisense, this is what you have to do:

Locate your schema, then copy it to C:\Progam Files\Microsoft Visual Studio .NET 2003\Common7\Packages\schemas\xml.

Then open your XML document and reference the schema by its namespace URI in the root element.

If you want to automate the update of your schema files the use scripting on the Visual Studio's OnStartupComplete event.

 

Virtualization

7. August 2006 08:53 by Mrojas in General  //  Tags:   //   Comments (0)
Some people here in Artinsoft is doing a great deal of work around virtualization. You should check out their posts.
I was preparing a test environment for an application and I needed to run my check in tests in several versions of windows and I found this article

Program Customized Testing Environments Without Trashing Your Machine 

which has been of great help for me in setting up a virtual test lab. I really recommend it. After you read it you will figure out great new test environments.
Like database tests. where you setup a virtual disk with your database, or diferrent images with diferent driver versions.

Good Luck!

AS400 from .NET

4. August 2006 05:19 by Mrojas in General  //  Tags:   //   Comments (0)

You might encounter certain scenarios where you have either VB6 applications that used information from an AS400 box or new .NET applications that need to get information in or out the AS400 box.

Usually this is done by creating RPG programs that generate plain text files that are transfered to PCs and processed by the VB6 or VB.Net application.

But would't it be great to access the AS400 directly, perform queries, execute programs, even use the AS400 users print jobs and other services.

IBM has a project call JTOpen, this is an open source java implementation of objects that allow you to access the AS400 box.  http://www-03.ibm.com/servers/eserver/iseries/toolbox/downloads.html

So why is this useful to you? This is in Java, what help could it give you? Because there is another interesting project called  IKVM.
I already posted about this project see  my post on IKVM  for more details.
With IKVM you can generate an assembly and use it in your projects.
You can start using this functionality directly in any of your VB.NET or C# projects.
If you have a VB6 applications, what are you waiting for: upgrade it now to VB.NET or expose this functionality thru a simple COM object and use it in VB6.
I'll post about this technique one this days.

And now enjoy accessing your AS400 from .NET

Regards

Taken Advantage of Java Open Source in .NET

4. August 2006 04:56 by Mrojas in General  //  Tags:   //   Comments (0)

We must recognize that there is a great amount of Java Open Source projects. It would be great to have access to all that code also in .NET but sometimes the migration of that functionality can take a while and you just need it right away.

For simple things you can use the J# implementations, and share your assemblies with C# and VB.NET applications. For medium things you might also think in using the JLCA so you will get a C# implementation ;) but some big projects could take more time that what you have available or taking a long time just does not worth it.

Well some guys have an superinteresting project. It is called IKVM. It allows you to compile your Java projects for .NET. IKVM.NET is an implementation of Java for Mono and the Microsoft .NET Framework.

This is an extract from their site http://www.ikvm.net/index.html:

Use Java libraries in your .NET applications

IKVM.NET includes ikvmc, a Java bytecode to .NET IL translator. If you have a Java library that you would like to use in a .NET application, run ikvmc -target:library mylib.jar to create mylib.dll.

For example, the Apache FOP project is an open source XSL-FO processor written in Java that is widely used to generate PDF documents from XML source. With IKVM.NET technology, Apache FOP can be used by any .NET application.

Develop .NET applications in Java

IKVM provides a way for you to develop .NET applications in Java. Although IKVM.NET does not include a Java compiler for .NET, you can use the open source Jikes compiler to compile Java source code to JVM bytecode, then use ikvmc -target:exe myapp.jar to produce a .NET executable. You can even use .NET API's in your Java code using the included ikvmstub application.

So if there was a Java Project that you were crying to use, stop now, wipe your tears and start using IKVM now.

Regards

Something like sprintf in C# or VB.NET

31. July 2006 11:11 by Mrojas in General  //  Tags: , , ,   //   Comments (0)

Recently I was wondering how to format  an output string like I used in C or C++ where we had the infamous and powerful sprintf but I could not find a good refence until I found this page.

http://blog.stevex.net/index.php/string-formatting-in-csharp/ I think it will be very useful to print it and have it close as a good cheat code sheet.

 

Lower Bounds not 0 in VB.NET

14. June 2006 17:31 by Mrojas in General  //  Tags:   //   Comments (0)
The other day a friend asked me. How could he created an array in VB with a lower bound different from 0.

In VB6 you could do something just like this:

Dim b(6 To 12) As Integer 

But in VB.NET it does not work that way. The LowerBound in VB.NET must be always 0. But there is a way to have a lower bound different from 0. It is unclear why this is not very documented but the following code shows how to do it: 

Dim b As Array = Array.CreateInstance(GetType(String), New Integer() {6}, New Integer() {6})

b(6) = 20

b(7) = 1

 

I received this comment:

Hi Mauricio RojaI am converting the VB6 programs to VB.Net2008. When I declare the array in VB.Net the lower bound always "0". When I searched internet got some clue from you. Thanks.Could you please help me to solve the array problem. I have declared a array as "public socketbins(1 to DUT, 1 to SOCK, 1 to 1000) as CBin" in VB6. When I convert this declaration to VB.Net2008 it is not accepted. can you please tell me how to declare the above declaration in VB.Net2008Thanks & RegardsUdhay

And this is my answer:

 

Hi.

Sorry for my late response.

I don’t know what you mean for CBin

But let's says the array type is byte

Then you can do this:

Dim socketBins4 = Array.CreateInstance(GetType(Byte), New Integer() {DUT, SOCK, 1000}, New Integer() {1, 1, 1})

And I am sending some code for your tests

 

Module Module1

Const DUT = 100

Const SOCK = 100

'taken and modified from http://blogs.msdn.com/vbfaq/archive/2004/04/20/116660.aspx

Public Class VBArray(Of T)

Private _lbound As Integer

Private _myitems() As T

Public Sub New(ByVal LBound As Integer, ByVal UBound As Integer)

Me.ReDim(LBound, UBound)

End Sub

Public Sub [ReDim](ByVal LBound As Integer, ByVal UBound As Integer)

_lbound = LBound

ReDim _myitems(UBound - LBound + 1)

End Sub

Default Public Property Item(ByVal Index As Integer) As T

Get

Return _myitems(Index - _lbound)

End Get

Set(ByVal Value As T)

_myitems(Index - _lbound) = Value

End Set

End Property

Public Function ToArray() As T()

Return _myitems

End Function

End Class

Sub Main()

 

Dim socketBins4 = Array.CreateInstance(GetType(Byte), New Integer() {DUT, SOCK, 1000}, New Integer() {1, 1, 1})

Dim arrayLenghts() As Integer = {DUT, SOCK, 1000}

Dim arrayLowerBounds() As Integer = {1, 1, 1}

Dim socketBins3 = Array.CreateInstance(GetType(Byte), arrayLenghts, arrayLowerBounds)

socketBins3(1, 1, 1) = 10

MsgBox("LBound for FirstDimension = " & LBound(socketBins3, 1))

MsgBox("LBound for SecondDimension = " & LBound(socketBins3, 2))

MsgBox("LBound for ThirdDimension = " & LBound(socketBins3, 3))

 

MsgBox("UBound for FirstDimension = " & UBound(socketBins3, 1))

MsgBox("UBound for SecondDimension = " & UBound(socketBins3, 2))

MsgBox("UBound for ThirdDimension = " & UBound(socketBins3, 3))

 

socketBins3(0, 0, 0) = 10 ' <--- This will throw an exception

 

'This are other possibilities

'This is not possible Dim socketbins(1 to DUT, 1 to SOCK, 1 to 1000) as Byte

Dim socketbins(0 To DUT, 0 To SOCK, 0 To 1000) As Byte

Dim socketBins2 As New VBArray(Of VBArray(Of VBArray(Of Byte)))(1, DUT)

'And then some init code here

 

End Sub

End Module

 

More Color to your Traces!

29. May 2006 08:37 by Mrojas in General  //  Tags: , ,   //   Comments (0)

Most Visual Basic programmers are familiar with using Debug.Print to follow their code's execution. The .NET environment introduces Tracing falicities that allows you to send messages to files or the console.

However the console output could be improved by using colors to highlight certain events. 
I developed a simple ColorTraceListener that can be used either with the My.Application.Log object or the Trace.TraceXXX methods. 
I first thing to do is create a ClassLibrary. It will be called ColorTraceListener. Add a ColorTraceListener.cs File and fill it with the following code:
 

Imports System

Imports System.Diagnostics

Imports System.Globalization

Imports System.Text

Imports System.Runtime.InteropServices 

Public Class ColorTraceListener

    Inherits ConsoleTraceListener

    Public Sub New()

        MyBase.New()

    End Sub 

    Public Sub New(ByVal useErrorStream As Boolean)

        MyBase.New(useErrorStream)

    End Sub 

    Friend Function IsEnabled(ByVal opts As TraceOptions) As Boolean

        Return ((opts And Me.TraceOutputOptions) <> TraceOptions.None)

    End Function 
 
 

    False)> _

    Public Overrides Sub TraceData(ByVal eventCache As TraceEventCache, ByVal source As String, ByVal eventType As TraceEventType, ByVal id As Integer, ByVal data As Object)

        If ((Me.Filter Is Nothing) OrElse Me.Filter.ShouldTrace(eventCache, source, eventType, id, Nothing, Nothing, Nothing, data)) Then

            Me.WriteHeader(source, eventType, id)

            Dim text1 As String = String.Empty

            If (Not data Is Nothing) Then

                text1 = data.ToString

            End If

            Me.WriteLine(text1)

            Me.WriteFooter(eventCache)

        End If

    End Sub 

    False)> _

    Public Overrides Sub TraceData(ByVal eventCache As TraceEventCache, ByVal source As String, ByVal eventType As TraceEventType, ByVal id As Integer, ByVal ParamArray data As Object())

        If ((Me.Filter Is Nothing) OrElse Me.Filter.ShouldTrace(eventCache, source, eventType, id, Nothing, Nothing, Nothing, data)) Then

            Me.WriteHeader(source, eventType, id)

            Dim builder1 As New StringBuilder

            If (Not data Is Nothing) Then

                Dim num1 As Integer = 0

                Do While (num1 < data.Length)

                    If (num1 <> 0) Then

                        builder1.Append(", ")

                    End If

                    If (Not data(num1) Is Nothing) Then

                        builder1.Append(data(num1).ToString)

                    End If

                    num1 += 1

                Loop

            End If

            Me.WriteLine(builder1.ToString)

            Me.WriteFooter(eventCache)

        End If

    End Sub 
 

    False)> _

    Public Overrides Sub TraceEvent(ByVal eventCache As TraceEventCache, ByVal source As String, ByVal eventType As TraceEventType, ByVal id As Integer, ByVal message As String)

        If ((Me.Filter Is Nothing) OrElse Me.Filter.ShouldTrace(eventCache, source, eventType, id, message, Nothing, Nothing, Nothing)) Then

            Me.WriteHeader(source, eventType, id)

            Me.WriteLine(message)

            Me.WriteFooter(eventCache)

        End If

    End Sub 
 

    False)> _

    Public Overrides Sub TraceEvent(ByVal eventCache As TraceEventCache, ByVal source As String, ByVal eventType As TraceEventType, ByVal id As Integer, ByVal format As String, ByVal ParamArray args As Object())

        If ((Me.Filter Is Nothing) OrElse Me.Filter.ShouldTrace(eventCache, source, eventType, id, format, args, Nothing, Nothing)) Then

            Me.WriteHeader(source, eventType, id)

            If (Not args Is Nothing) Then

                Me.WriteLine(String.Format(CultureInfo.InvariantCulture, format, args))

            Else

                Me.WriteLine(format)

            End If

            Me.WriteFooter(eventCache)

        End If

    End Sub 
 
 
 
 

    Private Sub WriteFooter(ByVal eventCache As TraceEventCache)

        If (Not eventCache Is Nothing) Then

            Me.IndentLevel += 1

            If Me.IsEnabled(TraceOptions.ProcessId) Then

                Me.WriteLine(("ProcessId=" & eventCache.ProcessId))

            End If

            If Me.IsEnabled(TraceOptions.LogicalOperationStack) Then

                Me.Write("LogicalOperationStack=")

                Dim stack1 As Stack = eventCache.LogicalOperationStack

                Dim flag1 As Boolean = True

                Dim obj1 As Object

                For Each obj1 In stack1

                    If Not flag1 Then

                        Me.Write(", ")

                    Else

                        flag1 = False

                    End If

                    Me.Write(obj1.ToString)

                Next

                Me.WriteLine(String.Empty)

            End If

            If Me.IsEnabled(TraceOptions.ThreadId) Then

                Me.WriteLine(("ThreadId=" & eventCache.ThreadId))

            End If

            If Me.IsEnabled(TraceOptions.DateTime) Then

                Me.WriteLine(("DateTime=" & eventCache.DateTime.ToString("o", CultureInfo.InvariantCulture)))

            End If

            If Me.IsEnabled(TraceOptions.Timestamp) Then

                Me.WriteLine(("Timestamp=" & eventCache.Timestamp))

            End If

            If Me.IsEnabled(TraceOptions.Callstack) Then

                Me.WriteLine(("Callstack=" & eventCache.Callstack))

            End If

            Me.IndentLevel -= 1

        End If

    End Sub 

    Private Sub WriteHeader(ByVal source As String, ByVal eventType As TraceEventType, ByVal id As Integer)

        Dim oldColor As ConsoleColor = Console.ForegroundColor

        Select Case eventType

            Case TraceEventType.Error

                Console.ForegroundColor = ConsoleColor.Red

            Case TraceEventType.Critical

                Console.ForegroundColor = ConsoleColor.Magenta

            Case TraceEventType.Information

                Console.ForegroundColor = ConsoleColor.White

                'Case TraceEventType.Resume

                'Case TraceEventType.Start

                'Case TraceEventType.Suspend

                'Case(TraceEventType.Transfer)

                'Case TraceEventType.Verbose

            Case TraceEventType.Warning

                Console.ForegroundColor = ConsoleColor.Yellow

        End Select

        Me.Write(String.Format(CultureInfo.InvariantCulture, "{0} {1}:", New Object() {source, eventType.ToString}))

        Console.ForegroundColor = oldColor

        Me.Write(String.Format(CultureInfo.InvariantCulture, " {0} : ", New Object() {id.ToString(CultureInfo.InvariantCulture)}))

    End Sub

End Class 

The methods that handle the headers in the TextWriteListener are private (WriteHeader and WriterFooter) so we need to override them. Reflector comes very handy in this cases. 

No to test it Create a Vb Console Application: 

Module Module1 

    Sub Main() 
 

        My.Application.Log.WriteEntry("Error!", TraceEventType.Error)

        My.Application.Log.WriteEntry("Warning", TraceEventType.Warning)

        My.Application.Log.WriteEntry("Info", TraceEventType.Information)

        My.Application.Log.WriteEntry("Info", TraceEventType.Critical) 

        Trace.TraceError("An Error Happened!")

        Trace.TraceInformation("Just letting you know!")

        Trace.TraceWarning("Watch the road ahead") 

    End Sub 

End Module 

And use a simple configuration file like the following: 

xml version="1.0" encoding="utf-8" ?>

<configuration>

    <system.diagnostics>

      <trace autoflush="true">

        <listeners>

          <add name="ColorLog" />

        listeners>

      trace>

        <sources>

            This section defines the logging configuration for My.Application.Log -->

            <source name="DefaultSource" switchName="DefaultSwitch">

                <listeners>

                    <add name="ColorLog"/>

                listeners>

            source>

        sources>

        <switches>

            <add name="DefaultSwitch" value="Verbose" />

        switches>

       <sharedListeners>

          <add name="ColorLog" type="Mrojas.ColorTraceListener, ColorTraceListener" />

        sharedListeners>

    system.diagnostics>

configuration> 
 

Migration and SOA

5. September 2005 05:49 by Mrojas in General  //  Tags:   //   Comments (0)

We have at Artinsoft performed migrations for several years, enabling clients to preserve the value of their applications.  In the last months it has been interesting to help clients evolve their applications applying an interesting new concept: SOA.

Service Oriented Architecture is not just a buzzword, it is a methology that empowers bussiness by teaching them to focus in goals instead of means.  Migrate a legacy application to a SOA architecture is more valueble because it allows an incremental aproach and provides means to get an immediate return on investment.