DetailPrint From Inside .NET DLL: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
(Performing a DetailPrint From Inside .NET DLL method.)
(Performing a DetailPrint From Inside .NET DLL method.)
Line 1: Line 1:
{{PageAuthor|claesabrandt}}
== Description ==
== Description ==
If your using the [[Call .NET DLL methods plug-in]] to call .NET DLL functions to perform work during an install, one of the things that will be useful is to be able to update the Details list in the installer, from the DLL, while a .NET DLL function call is executing. Below is some VB.NET code, easily converted to C# at [http://labs.developerfusion.co.uk/convert/vb-to-csharp.aspx DEVELOPERfusion], that provides a method '''DetailPrint''' that adds an ''entry'' to the end of the Details list.
If your using the [[Call .NET DLL methods plug-in]] to call .NET DLL functions to perform work during an install, one of the things that will be useful is to be able to update the Details list in the installer, from the DLL, while a .NET DLL function call is executing. Below is some VB.NET code, easily converted to C# at [http://labs.developerfusion.co.uk/convert/vb-to-csharp.aspx DEVELOPERfusion], that provides a method '''DetailPrint''' that adds an ''entry'' to the end of the Details list.
Line 137: Line 138:
• 1.0 First release.
• 1.0 First release.


[[User:Rbchasetfb|Rbchasetfb]] 07:07, 12 September 2008 (PDT)<br>
07:07, 12 September 2008 (PDT)


[[Category:Code Examples]]
[[Category:Code Examples]]

Revision as of 14:13, 12 September 2008

Author: claesabrandt (talk, contrib)


Description

If your using the Call .NET DLL methods plug-in to call .NET DLL functions to perform work during an install, one of the things that will be useful is to be able to update the Details list in the installer, from the DLL, while a .NET DLL function call is executing. Below is some VB.NET code, easily converted to C# at DEVELOPERfusion, that provides a method DetailPrint that adds an entry to the end of the Details list.

Below you'll find the VB.NET source code, this code is for a complete namespace and class and includes an example function ChopString to test with. You'll also find an NSIS test script. Lastly, a zip file is attached with the complete Visual Studio 2005 project for the test .NET DLL and the NSIS test script. Also included in the zip is ListViewDeclarations.vb that has all the declarations necessary for working with List-view controls from VB.NET. This file also has the DetailPrint method...all this is contained in a VB.NET #Region you can drop in your .NET DLL.

VB.NET Source Code

Imports System
Imports System.Runtime.InteropServices
 
Namespace NSIS
   Public Class TestClass
      'The LVITEM stucture specifies or receives the attributes of a list-view item.
      <StructLayout(LayoutKind.Sequential)> _
      Public Structure LVITEM
         Public mask As Int32
         Public iItem As Int32
         Public iSubItem As Int32
         Public state As Int32
         Public stateMask As Int32
         Public pszText As String
         Public cchTextMax As Int32
         Public iImage As Int32
         Public lParam As IntPtr
      End Structure
 
      'SendMessage API declarations. Two different declarations to manage two lparam types.
      Public Declare Function SendMessageLV Lib "user32" Alias _
         "SendMessageA"(ByVal hwnd As IntPtr, _
                        ByVal wMsg As Int32, _
                        ByVal wParam As Integer, _
                        ByRef lParam As LVITEM) As Integer
      Public Declare Function SendMessage Lib "user32" Alias _
         "SendMessageA"(ByVal hwnd As IntPtr, _
                        ByVal wMsg As Int32, _
                        ByVal wParam As Integer, _
                        ByRef lParam As Integer) As Integer
 
      'Constants used by LVITEM and SendMessage 
      Public Const LVM_FIRST as Integer = &H1000 
      Public Const LVM_GETITEMCOUNT as Integer = LVM_FIRST + 4
      Public Const LVM_GETITEM as Integer = LVM_FIRST + 5
      Public Const LVM_INSERTITEM as Integer = LVM_FIRST + 7
      Public Const LVM_SCROLL as Integer = LVM_FIRST + 20
      Public Const LVIF_TEXT as Integer = &H0001
      Public Const LVIS_FOCUSED as Integer = &H0001
 
      'Here's the key function that writes to the Details list.
      Public Sub DetailPrint(ByVal hwnd As IntPtr, entry as String)
         Try
            'Get current list count
            Dim c as Integer = SendMessage(hwnd,LVM_GETITEMCOUNT,0,0)+1
            'Setup a LVITEM structure for the Insert message
            Dim lv As New LVITEM
            lv.iItem = c
            lv.pszText = entry
            lv.mask = LVIF_TEXT
            lv.stateMask = LVIS_FOCUSED
            lv.state = LVIS_FOCUSED
            'Insert the LVITEM into the list
            c = SendMessageLV(hwnd, LVM_INSERTITEM, 0, lv)
            'Scroll the list so the item is visible
            SendMessage(hwnd,LVM_SCROLL,0,12)
         Catch ex As Exception
            'Do Nothing, no sense throwing an error just for logging.
         End Try
      End Sub
 
      'Test function for calling from an NSIS installer using CLR.dll
      Public Function ChopString(ByVal hwnd as IntPtr, ByVal stringToChop as String, _
                                 ByVal chopToLength as Integer) As String
         Dim ret as String = ""
         If stringToChop.Length > chopToLength Then
            DetailPrint(hwnd, "FROM DLL: Chopping String '" & stringToChop & "'")
            ret = stringToChop.SubString(0,chopToLength)
            DetailPrint(hwnd, "FROM DLL: String chopped to '" & ret & "'")
         Else
            DetailPrint(hwnd, "FROM DLL: String '" & stringToChop & _
            "' insufficient length to chop to " & chopToLength & " characters")
            ret = "error"
         End If
         Return ret
      End Function
   End Class
End NameSpace

NSIS Test Script

Name "Test CLRDLL MakeLogEntry"
OutFile "TestCLRDLL.exe"
ShowInstDetails show
Var DetailsHWND
Page instfiles
 
Function .onGUIEnd
   CLR::Destroy
FunctionEnd
 
Section
   InitPluginsDir
   SetOutPath $PLUGINSDIR
   File "TestCLRDLL.dll"
   DetailPrint "===================================="
   FindWindow $0 "#32770" "" $HWNDPARENT
   GetDlgItem $DetailsHWND $0 1016
   CLR::Call /NOUNLOAD "TestCLRDLL.dll" \
      "NSIS.TestClass" \
      "ChopString" \
      3 \
      $DetailsHWND "Testing Make Log Entry" 9
   Pop $0
   DetailPrint "ChopString Result = $0"
   DetailPrint "===================================="
   DetailPrint "Chopping a short string to gen error"
      CLR::Call /NOUNLOAD "TestCLRDLL.dll" \
      "NSIS.TestClass" \
      "ChopString" \
      3 \
      $DetailsHWND "Testing" 9
   Pop $0
   DetailPrint "ChopString Result = $0"
SectionEnd

Prerequisites

You'll need to have the CLR.dll in your NSIS plugins directory. You can get it from the Call .NET DLL methods plug-in page or here CLR.zip (35 KB).

Download

Here's the latest version of this little package including the Visual Studio 2005 project, NSIS Test Script and ListViewDeclarations.vb file. TestCLRDLL.zip (77 KB)

Acknowledgements

Many thanks to claesabrandt (the creator of Call .NET DLL methods plug-in) for the back-and-forth on getting the CLR.dll working smoothly without the need for anything other than .NET 2.0 Framework. That was some great team-work! This tool is awesome and is helping make a potentially ugly install a lot smoother.

Version History

• 1.0 First release.