Posts Tagged ‘.NET’

Microsoft POS Library for .NET

Thursday, October 14th, 2010

I’ve been writing a specialised point of sale system for a local business and had to use the POS printer on their till.  Fortunately, Microsoft have a nice library available for .NET that is freely downloadable that deals with most of the hard work of communicating with POS devices.

I was interested in the POSPrinter class.  They do provide a simulator so that you can test things out using the simulated printer, but it doesn’t support anything other than basic plain text, whereas I needed to use formatted text.

POS printers usually use a control language called ESC/POS.  This was developed by Epson originally for their POS printers, but it has become a standard.  Basically, it is mostly a matter of sending plain text, but you can also send certain escape sequences to change settings on the printer.

Fortunately, Microsoft document a lot of this on MSDN, so you don’t need to work it all out from scratch.  There are things like knowing that the main escape sequence is &H1B or 27 (known as ESC) and then a pipe character followed by optional numbers, small letters or symbols followed by a capital letter.  Eg. ESC|#P cuts the paper, ESC|bC is the code to turn on bold etc.

However, you may find it useful to have some sample code…


Imports Microsoft.PointOfService

Public Class POSPrinter

    Public Const ESC = Chr(&H1B) & "|"
    Public Const SetBold = ESC & "bC"
    Public Const SetUnderline = ESC & "uC"
    Public Const SetItalic = ESC & "iC"
    Public Const SetCentre = ESC & "cA"
    Public Const SetRight = ESC & "rA"
    Public Const ResetFormatting = ESC & "N"

    Public Shared Function SetSize(ByVal Size As Integer) As String
        Return ESC & Size & "C"
    End Function

    Public Shared Function GetAndInitPosPrinter() As Microsoft.PointOfService.PosPrinter
        Dim pe As New PosExplorer()
        Dim ppdi = pe.GetDevice(DeviceType.PosPrinter, My.Settings.PrinterName)
        Dim pp As Microsoft.PointOfService.PosPrinter = pe.CreateInstance(ppdi)
        pp.Open()

        pp.Claim(250)

        pp.DeviceEnabled = True

        Return pp
    End Function

    Public Shared Sub ReleaseAndClosePosPrinter(ByVal pp As Microsoft.PointOfService.PosPrinter)

        pp.Release()

        pp.Close()
    End Sub

    Public Shared Sub PrintTest()

    Dim pp As Microsoft.PointOfService.PosPrinter = Nothing

    pp = GetAndInitPosPrinter()

    Dim msg As String = "This is a test" & vbCrLf & SetBold & SetSize(3) & SetCentre & "it works" & SetSize(1) & " pretty well" & vbCrLf & "OK"

    pp.PrintNormal(PrinterStation.Receipt, msg)

    ReleaseAndClosePosPrinter(pp)

    End Sub


One other thing to watch out for is that if you are running any other POS software on the till, such as Microsoft Dynamics POS, then you might need to go into the settings and tell it to share the printer nicely with the other children applications as some POS software tends to be pretty possessive

Also, always make sure that you release and close any POS devices when you are done with them. For some reason when you start using them you need to open them, claim them and then enable them which seems ridiculous overkill to me, but what do I know?

Linq to SQL Query gives an InvalidOperationException with message “Cannot compare entities associated with different tables.”

Wednesday, September 15th, 2010

If you try to do a Linq to SQL query and it runs fine, but gives you an exception of type InvalidOperationException and the message is “Cannot compare entities associated with different tables.” then it probably means that you are trying to pass in an object of one type and compare it to another type.  I suspect that you will probably only get this error if Linq attempts to translate the error to SQL – if you run it in memory, you might not get an error at all, as it may just do a straight object comparison and conclude that they are different objects.

An example would be something like


Dim p = DBContext.People.First
Dim q = From a in DBContext.Addresses Where a Is p
Dim addr = q.First

The final line will result in this exception as Linq to SQL is attempting to translate the query into SQL and it (correctly) can’t find any way of writing a query that compares a person to an address!

Why I’m not posting how to get .NET 4.0 working in Windows 2000

Tuesday, August 3rd, 2010

The most popular part of my blog is the posts that I have made on how to get .NET 3.5 (partially) working in Windows 2000, so why am I not continuing this with .NET 4.0?

The truth is that I originally did the .NET 3.5 approach for a specific project where a client of mine had a large number of Windows 2000 PCs. I wanted to be able to use .NET 3.5, and I didn’t want him to be saddled with the upgrade costs. However, since then, he has been gradually replacing those PCs with Windows XP and now Windows 7 PCs, until he only had 2 or 3 Windows 2000 machines left. I recommended to him that it was better for him to upgrade/replace the last ones rather than me trying to get .NET 4.0 working on the old ones, which probably wouldn’t be as cost efficient.

I realise that this might be a disappointment to some people who have still got lots of Windows 2000 machines out there. If anyone does come up with a way of doing it (possibly based on my .NET 3.5 approach), please let me know and I’ll post it up, crediting you.

Finding a table in a Linq to SQL DBML file in Visual Studio 2008

Monday, March 1st, 2010

One problem that can take up a lot of time if you are working in a large project with a lot of tables in the DBML database model file when using Linq to SQL in Visual Studio is finding the table in the diagram.  Control+F doesn’t work, and it can be a real pain to scroll around for ages.  However, the following article mentions a very simple solution – just use the dropdown at the top of the properties window!  Seems obvious, but I know quite a few people have been complaining about that for months!

Taken from Is there a way to find a table in a DBML file in Visual Studio 2008? – Stack Overflow.

Windows Forms controls and the red X

Thursday, December 17th, 2009

I have been working on a project where certain controls randomly seem to come up with a red X and a red border around it.  I wasn’t sure what was causing it, but it turns out it is when an exception is thrown by code in the paint event.  For more details, see the following blog from sturmnet.org:  WinForms controls and the red X.

Exceptions Explained: NullReferenceException

Sunday, November 8th, 2009

This is the first on a new series of posts that I’m going to be doing on explaining various different exceptions, what they mean, when you might get them and how to avoid them.

The first one is the NullReferenceException, which usually comes with the message “Object reference not set to an instance of an object.”. This Exception occurs when you try to access an object reference which is set to Nothing.

First of all, you need to understand the difference between value types and reference types in .NET. With a value type, we only care about what data is stored within it. With a reference type, the actual instance of the type is important in itself. For example, we may have an Integer, which contains 10. Integers are value types, and there is generally nothing particularly different between one number 10 and another number 10 if they are both Integers, so they are effectively identical.

Reference types on the other hand are different. If we have two customers, and both of them happen to be called “John Smith”, we don’t want to treat them as being the same thing just because they have the same name. The other difference with reference types is that we can have an empty reference – Nothing (or null in c#).

In fact, behind the scenes, reference types store a location in memory of the instance. In older programming languages, such as C/C++, these were known as pointers, and you could actually access them just like a number and change the item that they were pointing to with arithmetic operators (+/-/increment/decrement etc.) This created a number of potential problems and so references were created to protect pointers from causing too much damage. References also the garbage collector to keep track of what is referencing an object instance so that the instance can be cleared up when it is no longer in use.

The NullReferenceException is thrown when you attempt to access an object reference which is set to Nothing. This can easily happen because as mentioned above, all variables of a reference type will be initialised to Nothing by the .NET framework if they have not been explicity set to something else.

For example,

        Dim c As Customer
        c.Name = "John Smith"

The second line in the above piece of code will throw a NullReferenceException as the variable c is still set to Nothing, and when the .NET framework attempts to access the Name field, it will find that the object does not exist.

This is easily resolved by setting c to whatever Customer you wish to use, or to a New Customer.

Getting the ASP.NET Development Web Server to use a root path

Friday, July 10th, 2009

ASP.NET 2.0 comes with a test webserver which can be run by simply pressing F5 in Visual Studio from a website project which is located on your PC.  The only problem is that for reasons best known to Microsoft, it launches with the site configured in a subfolder.  This isn’t always convenient, as you may have paths relative to the site root which prevent this being practical for testing.

In order to get around this problem, you need to take the following steps: –

First of all, configure Visual Studio so that you can launch the test server manually as follows: –

Under the Tools menu, select External Tools.
Add a new entry
Call it something like ASP.NET Development Server
Command is C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\WebDev.WebServer.EXE (you may need to alter the path for your local machine)
Arguments are /port:80 /path:$(ProjectDir) (note that you will need to leave a space on the end of this for it to work properly.  Also, you can change the port number if you wish)

Press OK.  You can now launch the development server from the new entry on your Tools menu.  This will show in your system tray.  You should probably remember to close it when you are done.

The next step is to configure your project to use the server.  Right click on your project and click Property Pages.  If an empty dialogue comes up, press cancel and repeat the process – it should work second time.  Under Start Options, select Use custom server and leave the Base URL blank.  You may wish to change the start action as well.

Once you are done, you can press F5 to start debugging.  Don’t forget that next time you open the project you will need to start the server from the tools menu before you start debugging again, otherwise it won’t work.

Also, bear in mind that if this is a copy of a remote site, things like database connection strings may need changing.  Don’t forget to be careful not to overwrite any settings when you copy back if that is the case!

If you do want to develop on a copy of the site, the Website menu has a useful option to Copy website.

.NET for Linux or Other Platforms – Novell Mono

Friday, July 10th, 2009

Whilst most of my work is done in VB.NET for Windows client and server PCs, I do also have a Linux server which I mostly am stuck coding in php on.  It would be nice if it were possible to code in .NET on it, and this is actually partially possible.

Novell have been working on a project called Mono over the last few years to create an alternative implementation of .NET for other platforms, including Linux.  They have implemented most of the major features and classes, but there are still a few areas which are patchy.  I usually find that the Handles VB.NET keyword doesn’t work and causes a compiler error, but it is quite possible to make a decent site that operates on Mono.  I’ve even compiled a DLL file in Visual Studio and used it in a Mono project’s Bin folder.  Of course if you do that, you have to be careful only to reference classes which are available in Mono.

Linq to SQL Quirks Part 4: Circular References

Friday, July 10th, 2009
This entry is part of a series, Linq to SQL Quirks»

In a project that I am working on at the moment, I have a situation where I have a Person table and a Family table.  The Person table has a FamilyID field, which is a foreign key to the Families ID (primary key) field, and the Family table has a DefaultPersonID, which is another foreign key back to Person to store the default contact for a family.

The problem is that if I create a new Person and Family with the Person being the DefaultContact, I get an InvalidOperationException thrown with a message “A cycle was detected in the set of changes”.  The problem is that Linq to SQL doesn’t know what to store first.  The only way that I have come up with to get around this is to do the following…

            If Person.ID = 0 AndAlso Not Person.Family Is Nothing Then
               
                Dim fam = Person.Family
                Person.Family = Nothing

                DBContext.SubmitChanges()
                Person.Family = fam

            End If

            DBContext.SubmitChanges()

This works by breaking the circular reference, so that there is only a 1 way reference, then submitting to the database, and once submitted, restoring the removed reference and submitting changes again

CType and DirectCast

Friday, July 3rd, 2009

VB.NET supports 2 different keywords which are related to casting.

DirectCast takes the object which is passed in and assumes it to be of the casted type or an inherited type.  This means that if you try to DirectCast an Integer to a Single, it won’t work.  If the compiler can see that it won’t work because it isn’t an inherited type, you’ll get a compiler error.  If you try it on a variable in eg. an Object at runtime, you’ll get an InvalidCastException.

The alternative is to use CType, which is much cleverer and will try to find a way to convert from one type to another.  This means that you can Ctype(“2.334”, Single) and it will parse the string and give you a Single length floating point number.  It will also check for overloading of the CType operator to see if it can convert using that.  This makes it very powerful, although it does come with the cost of a lot more processor usage.  However, for most modern applications, unless you are doing something heavily time constrained with a large amount of iterations in a  loop, it is unlikely to be an issue.