DetailPrint From Inside .NET DLL: Difference between revisions
Rbchasetfb (talk | contribs) (Performing a DetailPrint From Inside .NET DLL method.) |
Rbchasetfb (talk | contribs) (Performing a DetailPrint From Inside .NET DLL method.) |
||
Line 136: | Line 136: | ||
== Version History == | == Version History == | ||
• 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]] |
Revision as of 14:07, 12 September 2008
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.
Rbchasetfb 07:07, 12 September 2008 (PDT)
07:07, 12 September 2008 (PDT)