Showing posts with label .NET. Show all posts
Showing posts with label .NET. Show all posts

Wednesday, 15 August 2018

VB.NET Extending the MailMessage to have the ability to save the mail message

Problem:

The System.Net.Mail.MailMessage is badly missing the option of saving the Message as a file. Though there is a workaournd by using the SpecifiedPickupDirectory option of the SmtpClient to write the mail message ot the specific folder. This option however doesn't have flexibility in naming the files. In a multi-threaded parallel execution environment, it is difficult to identify and rename the specific files post writing to disk. There ought to be a better solution to handle this problem.

Solution:

You can extend the MailMessage class and add a Save method yourself. The Send method of the SmtpClient creates and uses MailWriter object to write out the mail message and it uses fileMailWriter when the SpecificPickupDirectory is specified as the DeliveryMethod. Create your own MailWriter object using FileStream and invoke the internal Send method, passing your MailWriter object. Check out this Code Project Article for more details. The code samples given there are for the C# language. Just in case you need, given below the same code for the Extension in VB.NET.


Imports System
Imports System.Net.Mail
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.IO
Imports System.Reflection
Imports System.Runtime.CompilerServices

Module MailMessageExtension
    <Extension()>
    Public Sub Save(ByVal msg As MailMessage, FileName As String)

        Dim asm As Assembly = New SmtpClient().GetType().Assembly
        Dim _mailWriterType As Type = asm.GetType("System.Net.Mail.MailWriter")


        Using _fileStream As FileStream = New FileStream(FileName, FileMode.Create)


            ' Get reflection info for MailWriter contructor
            Dim _mailWriterContructor As ConstructorInfo = _mailWriterType.GetConstructor(BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, New Type() {GetType(Stream)}, Nothing)

            ' Construct MailWriter object with our FileStream
            Dim _mailWriter As Object = _mailWriterContructor.Invoke(New Object() {_fileStream})

            ' Get reflection info for Send() method on MailMessage
            Dim _sendMethod As MethodInfo = New MailMessage().GetType().GetMethod("Send", BindingFlags.Instance Or BindingFlags.NonPublic)


            ' Call method passing in MailWriter

            _sendMethod.Invoke(msg, BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, New Object() {_mailWriter, True, True}, Nothing)

            ' Finally get reflection info for Close() method on our MailWriter
            Dim _closeMethod As MethodInfo = _mailWriter.GetType().GetMethod("Close", BindingFlags.Instance Or BindingFlags.NonPublic)

            ' Call close method
            _closeMethod.Invoke(_mailWriter, BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, New Object() {}, Nothing)
        End Using

    End Sub
End Module


You may observe that you need to create extensions as a module.

Sunday, 14 April 2013

How to Integrate a POS device in a .NET Windows Forms Application

Question:

One of our recent project requires integrating our Windows Forms application with point of sale devices like barcode scanner, check reader etc. I could find out that there is a POS.NET library that can be used for the purpose, but it seems to have been built for .NET 1.12 and no updates after that. Can you suggest me if there is any other .NET libraries that can be used for the purpose. You may also help me by sharing your thoughts and ideas.

Question by Selvamurugan N.

Answer:

Answering your first part of the question - Why there are n't any updates to this library? - I can only guess the answer for this and that I feel is due to the fact the device manufacturers lag behind in updating the communication protocols, which is more so because typically these devices are built for a low cost specific purpose operating environments. For instance, the POS terminals don't have to be on a Windows 7, it would just be enough for them to be on Windows XP or even older operating system. That probably is the reason, why the Library continues to be based on COM components and does not need an update.

On using the POS.NET library, yes, you can still use it in the later frameworks of .NET, but be aware of some of the constraints or issues as described in this blog post. The blog author calls out issues with 64 bit environment and also with .NET Framework 4.0. Don't miss out the comments, as there are some valid opinions and observations in the form of comments. You may also want to check out the Microsoft's publication on using the POS.NET titled as Creating a Proof of Concept POS Application.

If that does not suit you, then go ahead and learn to access and work with USB devices using HID (Human Interface Device), but you need to know the communication protocols and the data structures as specified by the device manufacturer. This will for sure will give you a better control over your integration, but you would be re-inventing the wheel. Here is a nice introduction to working with USB devices in .NET.

My recommendation is that check out if the device vendor provides you a .NET or a COM Library and if yes, using that will be the best option as some device manufacturers may have built certain proprietary protocols, which would work best with their own drivers. If that is not the case, then evaluate POS.NET whether it fits your use cases. Most of the times it should be fine, unless you meet up with some of the constraints when using with later versions of .NET Framework. If left with no choice, use HID interface to have your requirements met. You may also want to check out this msdn article on using Alternate Input Devices.