.NET Calculate week number of a date

20. March 2009 06:32 by Mrojas in General  //  Tags: , , ,   //   Comments (0)
This post shows a way to calculate the number of weeks.
Remember that this calculation is culture-dependant
For example the GetWeekOfYear methods requires a criteria to determine 
how to determine the first week and which day to consider as FirstDayOfWeek for more info see here:

CalendarWeekRule.FirstDay

Supported by the .NET Compact Framework.

Indicates that the first week of the year starts on the first day of the year and ends before the following designated first day of the week. The value is 0.

CalendarWeekRule.FirstFourDayWeek

Indicates that the first week of the year is the first week with four or more days before the designated first day of the week. The value is 2.

CalendarWeekRule.FirstFullWeek

Indicates that the first week of the year begins on the first occurrence of the designated first day of the week on or after the first day of the year. The value is 1.

 

 

Sample Code

        Dim x As Date
        Dim currentCulture As System.Globalization.CultureInfo
        currentCulture = CultureInfo.CurrentCulture
        Dim weekNum = currentCulture.Calendar.GetWeekOfYear(x, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday)

Get path of ASP.NET web application that is running

If you have your ASP.NET application for example in c:\inetpub\wwwroot\WebApplication1 and you want to programmatically get that path just use something like:

 

string AppPath = Request.PhysicalApplicationPath;

Resizing Forms in C#

In the VB6 world it was very common to use “Resizer” OCXs that you just put on your forms and that they handle all the proportional resizing needed if you changed your form.

It was very simple and easy.

However when I started looking for something like that in .NET it was quite hard to find. So finally I got to ComponentSource and found some alternatives and I evaluated them:

 

Component Vendor Pricing URL
Component One Sizer For .NET Component ONE I think you have to buy the Component One Studio. That’s $800 ($1000 with more support)
and I think is one license per developer, runtime-free
http://www.componentone.com/SuperProducts/StudioWinForms/
.NET Forms Resize Softgroup 380$ per developer
from ComponentSource
if you buy directly from them you can get the component for 180$

Each copy is licensed on a per developer basis. A developer may use the license on multiple CPUs as long as they are not used concurrently nor used by another developer. Run-time royalty free.
http://www.soft-group.it/net/index.php?c=3a&id=11
Resize OCX/.NET Larcom and Young 95$-100$ per license

one license per developer, runtime-free
http://www.lyoung.com/

 

All of them seem to work. So it really up to your company preferences, budget and the level of support you desire. I haven't made tests like how it behaves if you have thirdparty components or activex ??? maybe I'll review that later.

Calling .NET from PowerBuilder

3. March 2009 08:14 by Mrojas in General  //  Tags: , , , , ,   //   Comments (0)

Most of our clients come from a medium-size to a big enterprise level. In these scenarios is very common to have different department using different technologies to solve their business needs.

These different technologies can be on a very homogeneous platform like .NET where you can easily interact between your VB.NET and C# assemblies, or they could be on differente technologies like ASP, Classic VB, C++, or Powerbuilder.

This post is about PowerBuilder, and in order to interact with PowerBuilder I think the easiest way is to expose your assemblies thru COM Interop.

So if there is some .NET functionality that you want to expose to PowerBuilder you just need to expose that functionality with a class in a ClassLibrary project with COM attributes.

Let’s begin with a simple program to show how to comunicate Powerbuilder with C#.

NOTE:  If you don’t have Powerbuilder you can get a trial version from: http://www.sybase.com/detail?id=1052162

  1. Open Microsoft Visual Studio
  2. On the File Menu, choose the New option, and in the File submenu choose Project….

Visual Studio File Menu

Figure 1. Visual Studio File Menu. Choosing the option for a new project

  1. When you choose that option a dialog window will shown with the available options for new projects. In the option for C# Projects choose “Class Library”

image

Figure 2. New Project dialog window

You must introduce the new project name, location and solution name. Type something like ClassLibrary1, D:\PowerBuilder, ClassLibrary1.

1. When you finish creating your project you will have a code file called Class1.cs.

2. Change that code for something like :

using System;
using System.Collections.Generic;
using System.Text;

namespace SimpleClass
{
    public class Class1
    {
        public int AddTenToParameter(int param1)
        {
            return param1 + 10;
        }

        public void SayHi()
        {
            System.Windows.Forms.MessageBox.Show("Hello World!");
        }

        public String GiveMeDate()
        {
            return DateTime.Now.ToLongDateString();
        }
    }
}

This will allow to test things like parameter passing, using different return types like strings or integers. But Before you continue you must add a reference to System.Windows.Forms to be able to use the MessageBox.

 

Context Menu to add a reference

Figure 3. Adding a reference

 

Dialog with References

Figure 3. Reference to System.Windows.Forms

3. Right click on the solution file and select properties:

Project properties

Figure 4. Option to change project properties

4. Select the Register for COM Interop  checkbox

Register for COM

Figure 5. Project properties window

5. Return to Class1.cs code file

6. Add an using statement after the existing using lines on Class1.cs file:

using System.Runtime.InteropServices;

7. Add the following attributes to the class:

[ComVisible(true)]

[ClassInterface(ClassInterfaceType.AutoDual)]

[ProgId("ClassLibrary1.Class1")]

Note: the ProgId is very important, because these value will be use in PB to comunicate with the this code

8. Now you must edit the AssemblyInfo.cs

AssemblyInfo file

Figure 6. AssemblyInfo.cs File

Now make sure to establish the COM settings in this file with statements like the following:

// Setting ComVisible to false makes the types in this assembly not visible

// to COM components. If you need to access a type in this assembly from

// COM, set the ComVisible attribute to true on that type.

[assembly: ComVisible(true)]

// The following GUID is for the ID of the typelib if this project is exposed to COM

[assembly: Guid("69efac5b-d887-40f4-a7e9-2721ac3c1598")]

 

The Guid is also very important, because this is used to differentiate this component and it must be unique.

To generate a new GUID you can got to the Tools Menu and choose the option Create GUID

Create GUID menu option

Figure 7. Option menu to create a GUID

In the Create Guid dialog box, choose the fourth option and press Copy to put the contents on the Clipboard. Later, copy that value in the GUID attribute but remove the “{“ y “}”.

Now we are set. You only need to build the solution and the DLL. The build process with register the COM component.

If you will use the component on another computer you need to create an instalation program.

 

Using your program from Powerbuilder

Using your program from Powerbuilder is very easy. You just need code like the following:

image

Figure 8. PB Code to call a C# class thru COM

When you execute this program you will have 3 messageboxes :

  • Hello World!
  • 30
  • Monday, March 02, 2009 (this message will change depending of the day, locale and regional settings)

 

Creating an instalation program

  1. Right click the solution and in the context menu choose Add and then new project.

Context Menu for Adding new project to solution

Figure 9. Context Menu to add a new project

On the dialog box for Add New projec, look for the Other Project Types section and the choose Setup Project.

Adding a setup project

Figure 10. Creating a setup project

In this dialog bos indicate the name and location of the setup project. For example Setup1 and D:\Powerbuilder\ClassLibrary1.

Later, add a project to the setup program. To do that rigth click on the setup project and select Add, and in the submenu choose Project Output.

 

image

Figure 11. Adding a project to the setup project.

A dialog box will be shown with a combo that allow you to select the proyects in the solution. Choose ClassLibrary1 and press OK.

Add Project Output Dialog

Figure 12. Adding project output to the setup project.

When you build this instalation program two files will be produced:

Release

D:\PowerBuilder\ClassLibrary1\Setup1\Release\Setup.exe

D:\PowerBuilder\ClassLibrary1\Setup1\Release\Setup1.msi

Debug

D:\PowerBuilder\ClassLibrary1\Setup1\Debug\Setup.exe

D:\PowerBuilder\ClassLibrary1\Setup1\Debug\Setup1.msi

When you run the instalation program, this program will handle the instalation of the .NET component and the COM registration.

Project not generating the TLB

13. February 2009 04:01 by Mrojas in General  //  Tags: , , , ,   //   Comments (0)

My good friend Jafet, was recently dealing with an interesting bug in Visual Studio.

He created a simple Visual Studio Project that had just an interface that he exposed thru COM. He’s intention was to compile the Class Library and use the TLB file in other projects, but after building the solution he found out that there was no TLB file generated.

After some tests he finally found out that Visual Studio does not generates a TLB if there are not classes in the Project. So your options are, add a dummy class to your project or invoke the TLB tool from the command line.

:)

Debug XBAP using WinForms Host

26. January 2009 06:13 by Mrojas in General  //  Tags: , , , , ,   //   Comments (0)

Recently I had to deal with targeting an XBAP application that had some Windows Forms controls.

The problem is that those controls can only be used in a trusted environment. If you try to debug an XBAP with some Windows Forms Controls you will get an exception like:

Message: Cannot create instance of 'Page1' defined in assembly 'XBAPWithWinForms, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Exception has been thrown by the target of an invocation.  Error in markup file 'Page1.xaml' Line 1 Position 7.

It took me a while to found a solution, and it was thru Scott Landford Blog that I found a way around.

In short what he recommends to do is:

Change your settings to:

Start Action->Start external program = %windir%system32\PresentationHost.exe

  In my case (and the case of most people that is: c:\windows\system32\PresentationHost.exe)


Start Options->Command line arguments = -debug "c:\projects\myproject\bin\debug\MyProject.xbap" -debugSecurityZoneUrl "http://localhost:2022"

Copy the value from the Start URL after the –debug argument

Very import for using WinForms components you must run in FULL TRUST

fullTrust

 

Here is some XBAP code using a WinForms WebBrowser. They designer does not like it a lot but it works:

XBAPWithWinforms.zip

Welcome back Basic!!

15. January 2009 05:15 by Mrojas in General  //  Tags: , , ,   //   Comments (0)

My first language ever was GW-Basic. I was a teenager doing in summer work at a company that made polls about hair products and things like that. At that time I didn’t had a computer. They were tooooo expensive.

And I found a manual for GW-Basic. I stole it, to make a copy, my boss found out and he fired me :(. But then I had the power!! jeje. With my cousin Esteban we started out first programs. And we got our first sale :) :) :). It was the typical POS software for a small video rental  company.

Ahhh, and that was just the beginning.

So, I really appreciate basic, with all its strengths and weaknesses. I do most of my development now in C#, I think due to my C++, java years, and know I am more used to its syntax, and I really prefer C#. But I consider Basic a real treasure.

Well recently while digging in the Microsoft Dev Labs I discovered SmallBasic. I was just browsing for some new stuff and I am glad to have found this jewel.

Artinsoft (the company I work for) is a company that has devoted a lot of time in the research of automatic software migration to other platforms.Not for nothing one of our flapship products is Visual Basic Upgrade Companion, so basic in any form is always a delight for me. (I will soon post a brief article about bringing VBScript back to life in VB.NET just wait and see)

Ok. Back to SmallBasic.

 

First of all. The interface is great!!!

image IDE

It has a cool intellisense guide and you can even extend it :)

 

And they even resurrected LOGO!

image

I just hope to write a cool Turtle Graphics routine soon!

:)

The new way for Installing on the GAC

7. January 2009 11:36 by Mrojas in General  //  Tags:   //   Comments (0)

A long long time ago, I faced the problem of installing an assembly on the GAC from code. And I even posted the code in my blog

 http://blogs.artinsoft.net/mrojas/archive/2008/04/09/install-assembly-gac-with-c.aspx

 

Recently Jose Cornejo wrote me on my blog because the code was not working, and he finally showed me the right way to do it. It was sooo easy.

His solution was:

1. Add a reference to System.EnterpriseServices.dll to your project

2. Write code like the following:

            System.EnterpriseServices.Internal.Publish p = new Publish();
            p.GacInstall(@"C:\ClassLibrary1.dll");
            p.GacRemove(@"C:\ClassLibrary1.dll");

 

Thanks a lot Jose for your help.

Unofficial VarPtr, StrPtr, and ObjPtr migration to C#

6. January 2009 09:46 by Mrojas in General  //  Tags:   //   Comments (0)

These interesting functions have a long history, since the BASIC language, QuickBasic
and earlier versions of Visual Basic.  There isn’t much documentation on them but you
can look at very good reference as the one published by Matthew Curland
titled Unofficial Documentation for VarPtr, StrPtr, and ObjPtr

Well enough history, now let’s get back to the the migration part. If you’re reading this
post it might be, because you have VarPtr, StrPtr or ObjPtr calls in your code and you
want to move those calls to C#.

Well we have good and bad news.

Bad news are that the .NET world is a lot different than VB. Remember that your code
is running in the managed sandbox, and to get the address of variable you are probably
dealing with unmanaged memory, so some things might not work.

Good news are that I am one of those that believe that there are no imposibles,
it’s just a matter of the cost of developing the solution :)

Let’s see at some alternatives:

VarPtr can be use to get pointers to vaiables. This can be solved using Unsafe code:

VB6

  Dim l As Long
  Debug.Print VarPtr(l)

C#

    class Program
    {
        [DllImport(@"DllTest1.Dll")]
        static extern void Foo(IntPtr p);
        static void Main(string[] args)
        {
            int l;
            unsafe
            {
                int* pointerToL = &l;
                Foo((IntPtr)pointerToL);
                // Print the address stored in pointerToL:
                System.Console.WriteLine(
"The address stored in pointerToL: {0}", (int)pointerToL); } } }
And The implementation for Foo is a C function like:
extern "C" 
{
__declspec(dllexport)  void Foo(int* data)
{
    *data = 100;
}
}
Unsafe code like this will work for VarPtr cases where you have primitive types, 
like int, short, char variables.
Structures are more tricky and you will require pinning the memory to avoid some 
other problems. But in general doing Interop with structures is very tricky and
I will publish another post about this.
Unsafe code must be enabled at the assembly level and the assembly might need to 
be signed.
StrPtr is very similar to VarPtr but it mostly to provide efficient marshalling 
to Unicode functions. In most of cases like:
  Declare Sub MyUnicodeCall Lib "MyUnicodeDll.Dll" _
      (ByVal pStr As Long)

   Sub MakeCall(MyStr As String)
      MyUnicodeCall StrPtr(MyStr)
   End Sub
The StrPtr declaration is no longer needed because the .NET Interop mechanism can 
handle most of this marshaling automatically.
ObjPtr is the most tricky of all because it can be used in COM scenarios to get 
pointers to Interfaces implemented by a class.
In .NET scenarios this will involve only using classes that are exposed by COM. 
I have use code as the following
for some of those cases:
            Object myComObject = null;
            //..init code
            IntPtr pIUnknown = Marshal.GetIUnknownForObject(myComObject);
            IntPtr pIDesiredInterface = IntPtr.Zero;
            Guid guidToDesiredInterface = new Guid("XXXXXXXX-XXXX-XXXX");
            Marshal.QueryInterface(pIUnknown, 
ref guidToDesiredInterface,out pIDesiredInterface);

As always there are exceptions to the rule. These are just some general solutions. 
Directly accessing the memory is really something not desirable in a .NET application and in most
cases you should remove that code for something else, but if you can’t I hope these examples
guide you in this process.

Use C++ in C#

19. December 2008 07:00 by Mrojas in General  //  Tags: , , , , , ,   //   Comments (0)

COM


The idea is to make a class or several classes available thru COM. Then the compiled dll or the TLB is used to generate and Interop Assembly and call the desired functions.

With this solution the current C++ code base line can be kept or might require just subtle changes. 

Calling a function thru com is involved in a lot of marshalling and can add an additional layer that is not really needed in the architecture of the solution.

Creating a Managed Wrapper with Managed C++

The idea with this scenario is to provide a class in Managed C++ that will be available in C#. This class is just a thin proxy that redirects calls to the Managed object. 

Let’s see the following example: 

If we have a couple of unmanaged classes like: 

class Shape {

public:

  Shape() {

    nshapes++;

  }

  virtual ~Shape() {

    nshapes--;

  };

  double  x, y;  

  void    move(double dx, double dy);

  virtual double area(void) = 0;

  virtual double perimeter(void) = 0;

  static  int nshapes;

}; 
 

class Circle : public Shape { 

private:

  double radius;

public:

  Circle(double r) : radius(r) { };

  virtual double area(void);

  virtual double perimeter(void);

}; 
 

The first thing we can try, to expose our classes to .NET it to set the setting for managed compilation: 

Es posible que tu navegador no permita visualizar esta imagen.Es posible que tu navegador no permita visualizar esta imagen. 

If your project compiles then you are just very close, and what you need is to add some managed classes to your C++ project to expose your native classes: 

Let’s see the Shape class: 

//We can use another namespace, to avoid name collition.

//In this way we can replicate the structure of our C++ classes. 

namespace exposedToNET

{

      //Shape is an abstract class so the better thing

    // to do is to generate an interface 

      public interface class Shape : IDisposable

      {

      public:  

            //public variables must be exposed as properties

            property double x

            {

                  double get();

                  void set(double value);

            }

            property double y

            {

                  double get();

                  void set(double value);

            }

            //method do not expose any problems

            void move(double dx, double dy);

            double area();

            double perimeter();

            //public static variables must

          //be exposed as static properties

          //However we might need to create a new class

          //for all public static variables and methods

          //because C# does not accept methods in an interface

            static property int nshapes;

      };

      //Static methods or variables of abstract class are added here

      public ref class Shape_Methods

      {

                        //public static variables must be exposed as static properties

      public:

            static property int nshapes

            {

                  int get()

                  {

                        return ::Shape::nshapes;

                  }

                  void set(int value)

                  {

                        ::Shape::nshapes = value;

                  }

            } 

      };

} 

And for the Circle class we will have something like this: 

namespace exposedToNET

{ 
 

      public ref class Circle : Shape

      {

      private:

            ::Circle* c;

      public:

            Circle(double radius)

            {

                  c = new ::Circle(radius);

            }

            ~Circle()

            {

                  delete c;

            }

            //public variables must be exposed as properties

            property double x

            {

                  virtual double get()

                  {

                        return c->x;

                  }

                  virtual void set(double value)

                  {

                        c->x = value;

                  }

            }

            property double y

            {

                  virtual double get()

                  {

                        return c->y;

                  }

                  virtual void set(double value)

                  {

                        c->y = value;

                  }

            }

            //method do not expose any problems

            virtual void move(double dx, double dy)

            {

                  return c->move(dx,dy);

            }

            virtual double area()

            {

                  return c->area();

            }

            virtual double perimeter()

            {

                  return c->perimeter();

            }

            //public static variables must be exposed as static properties

            static property int nshapes

            {

                  int get()

                  {

                        return ::Shape::nshapes;

                  }

                  void set(int value)

                  {

                        ::Shape::nshapes = value;

                  }

            } 
 

      }; 

}

DOWNLOAD EXAMPLE CODE

SWIG

 

SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages.

This is a great tool used for several languages like Python, Perl, Ruby, Scheme, and even in different platforms.

The exposure mechanism used in this scheme is platform invoke, the issues here are similar to those of COM because there is some marshaling going on. This scheme might be more efficient than the COM one but I haven’t really test it to be completely sure that it is better. 

I have reviewed the SWIG code and it might also be possible to modify its code to generate wrappers using managed C++, but this is an interesting exercise that I have to leave for my readers. Sorry I just don’t have enough time. 

But how is SWIG used? 

In SWIG what you do is that you add a .i file to your project. This file provides directives for some code generation that specify exactly what you want to expose and how. 

This can very helpful if you just want to expose some methods. 

If you are lazy like me you can just add something like: 

/* File : example.i */

%module example 

%{

#include "example.h"  ß you put here includes with the definitions for your classes

%} 

/* Let's just grab the original header file here */

%include "example.h" ß add alse the include here 

And SWIG will add a file like example_wrap.cxx that you have to compile with the rest of your C++ code. 

It will also generate a set of C# classes that you use in your C# application, so it seams to your program that all the code is just C#.  

SWIG is a great tool and has been testing in a lot of platforms.