Howard Kaikow Posted June 22, 2006 Posted June 22, 2006 Without using the System.IO, etc, libraries, I'd like to find an example of how to use the Unicode API functions FindFirstFileW and FindNextFileW in VB .Net. The goal is to convert the VB 6 code to VB .Net. Quote
Wile Posted June 22, 2006 Posted June 22, 2006 I havent looked at the vb code, but if you need to use API functions instead of .net methods to avoid a problem, a good starting point is http://www.pinvoke.net/index.aspx This is a wiki containing most (if not all) of the windows API with definition (and often examples) to pinvoke them -> call them from .net. For FindFirstFile it finds: http://www.pinvoke.net/default.aspx/kernel32/FindFirstFile.html Hope this helps. Quote Nothing is as illusive as 'the last bug'.
Howard Kaikow Posted June 22, 2006 Author Posted June 22, 2006 I havent looked at the vb code, but if you need to use API functions instead of .net methods to avoid a problem, a good starting point is http://www.pinvoke.net/index.aspx This is a wiki containing most (if not all) of the windows API with definition (and often examples) to pinvoke them -> call them from .net. For FindFirstFile it finds: http://www.pinvoke.net/default.aspx/kernel32/FindFirstFile.html Hope this helps. THanx. Looks like a useful site, Is the following the Unicode version? [DllImport("kernel32", CharSet=CharSet.Unicode)] public static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData); Quote
Howard Kaikow Posted June 22, 2006 Author Posted June 22, 2006 THanx. Looks like a useful site, Is the following the Unicode version? [DllImport("kernel32", CharSet=CharSet.Unicode)] public static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData); Ah, I see that it is the Unicode version! Quote
Administrators PlausiblyDamp Posted June 22, 2006 Administrators Posted June 22, 2006 Just out of curiosity is there a reason you don't want to switch to the .Net way of ding things (System.IO etc.)? It would really allow you to simplify the existing code if you dropped the interop stuff. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
Howard Kaikow Posted June 22, 2006 Author Posted June 22, 2006 Just out of curiosity is there a reason you don't want to switch to the .Net way of ding things (System.IO etc.)? It would really allow you to simplify the existing code if you dropped the interop stuff. Yes, I'm testing something. I've converted the code at pinvoke.net to VB .NET, but there's a problem because I do not know how to pass the parameters in the unicode version. When I get to hSearch = FindFirstFileW(Path & "*", WFD) I get "Additional information: Object reference not set to an instance of an object.". Do not know which object is being referenced. Option Explicit On Option Strict On Option Compare Text Imports System.Runtime.InteropServices 'Imports Microsoft.VisualBasic.ControlChars Imports System.IO Public Class Form1 Inherits System.Windows.Forms.Form <DllImport("kernel32", CharSet:=CharSet.Unicode, SetLastError:=False)> _ Private Shared Function FindClose _ (ByVal hFindFile As Integer) As Integer End Function <DllImport("kernel32", CharSet:=CharSet.Unicode, SetLastError:=True)> _ Private Shared Function FindFirstFileW _ (ByVal lpFileName As String, ByVal lpFindFileData As WIN32_FIND_DATA) As Integer End Function <DllImport("kernel32", CharSet:=CharSet.Unicode, SetLastError:=True)> _ Private Shared Function FindNextFileW _ (ByVal hFindFile As Integer, ByVal lpFindFileData As WIN32_FIND_DATA) As Integer End Function <DllImport("user32", CharSet:=CharSet.Unicode, SetLastError:=False)> _ Private Shared Function SendMessage _ (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByRef lParam As Integer) As Integer End Function Private Structure FILETIME Dim dwLowDateTime As Integer Dim dwHighDateTime As Integer End Structure Private Const ALTERNATE As Integer = 14 Private Const FILE_ATTRIBUTE_DIRECTORY As Integer = &H10S Private Const INVALID_HANDLE_VALUE As Integer = -1 Private Const MAX_PATH As Integer = 260 Private Const LB_GETCOUNT As Integer = &H18BS Private Const LB_SETHORIZONTALEXTENT As Short = &H194S Private Const LB_SETTOPINDEX As Integer = &H197S <Serializable(), StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _ Private Structure WIN32_FIND_DATA Dim dwFileAttributes As FileAttributes Dim ftCreationTime As FILETIME Dim ftLastAccessTime As FILETIME Dim ftLastWriteTime As FILETIME Dim nFileSizeHigh As Integer Dim nFileSizeLow As Integer Dim dwReserved0 As Integer Dim dwReserved1 As Integer <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_PATH)> _ Dim cFileName As String <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=ALTERNATE)> _ Dim cAlternate As String End Structure Private Sub frmFindFirstFile_Activated(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Activated 'With lstStuff ' 'UPGRADE_ISSUE: Constant vbPixels was not upgraded. Click for more: 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="vbup2070"' ' 'UPGRADE_ISSUE: Constant vbTwips was not upgraded. Click for more: 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="vbup2070"' ' 'UPGRADE_ISSUE: Form method frmWFDTest.ScaleX was not upgraded. Click for more: 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="vbup2064"' ' SendMessage(.Handle.ToInt32, LB_SETHORIZONTALEXTENT, ScaleX(VB6.PixelsToTwipsX(.Width), vbTwips, vbPixels) + 5000, 0) 'End With End Sub Private Sub btnRunMe_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRunMe.Click Dim lngCount As Integer Dim sFileName As String sFileName = txtDriveLetter.Text & ":\" ' Can be up to 32,767 chars lstStuff.Items.Clear() lngCount = 0 FindMyFiles(sFileName, lngCount) End Sub Private Sub FindMyFiles(ByRef Path As String, ByRef lngFileCount As Integer) Dim k As Integer Dim NumberDirectories As Integer Dim strListDirectoryNames() As String ' The following can be Static or Private Dim Filename As String Dim hSearch As Integer Dim WFD As WIN32_FIND_DATA NumberDirectories = -1 'hSearch = FindFirstFileW(StrPtr(Path & "*"), VarPtr(WFD)) hSearch = FindFirstFileW(Path & "*", WFD) If hSearch <> INVALID_HANDLE_VALUE Then With txtProcessed Do System.Windows.Forms.Application.DoEvents() Filename = RemoveNulls(WFD.cFileName) If (Filename <> ".") And (Filename <> "..") Then If (WFD.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY) = 0 Then lngFileCount = lngFileCount + 1 .Text = FormatNumber(lngFileCount, 0, , , TriState.True) ' With lstStuff ' .AddItem lngFileCount & ": " & Path & Filename ' k = SendMessage(.hwnd, LB_GETCOUNT, ByVal 0&, ByVal 0&) ' SendMessage .hwnd, LB_SETTOPINDEX, k - 1, ByVal 0& ' End With Else NumberDirectories = NumberDirectories + 1 ReDim Preserve strListDirectoryNames(NumberDirectories) strListDirectoryNames(NumberDirectories) = Filename End If End If 'Loop While FindNextFileW(hSearch, VarPtr(WFD)) <> 0 Loop While FindNextFileW(hSearch, WFD) <> 0 End With k = FindClose(hSearch) End If If NumberDirectories <> -1 Then For k = 0 To NumberDirectories FindMyFiles(Path & strListDirectoryNames(k) & "\", lngFileCount) Next k End If End Sub Private Function RemoveNulls(ByRef OriginalString As String) As String Dim pos As Integer pos = InStr(OriginalString, Chr(0)) If pos > 1 Then RemoveNulls = Mid(OriginalString, 1, pos - 1) Else RemoveNulls = OriginalString End If End Function End Class Quote
Howard Kaikow Posted June 23, 2006 Author Posted June 23, 2006 Using FindFirstFileW, how does one convert the following to VB .NET, given the structures below, where Path is type String? hSearch = FindFirstFileW(StrPtr(Path & "*"), VarPtr(WFD)) Dim WFD As WIN32_FIND_DATA <DllImport("kernel32", CharSet:=CharSet.Unicode, SetLastError:=True)> _ Private Shared Function FindFirstFileW _ (ByVal lpFileName As String, ByVal lpFindFileData As WIN32_FIND_DATA) As Integer End Function Private Structure FILETIME Dim dwLowDateTime As Integer Dim dwHighDateTime As Integer End Structure Private Const ALTERNATE As Integer = 14 Private Const MAX_PATH As Integer = 260 <Serializable(), StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _ Private Structure WIN32_FIND_DATA Dim dwFileAttributes As FileAttributes Dim ftCreationTime As FILETIME Dim ftLastAccessTime As FILETIME Dim ftLastWriteTime As FILETIME Dim nFileSizeHigh As Integer Dim nFileSizeLow As Integer Dim dwReserved0 As Integer Dim dwReserved1 As Integer <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_PATH)> _ Dim cFileName As String <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=ALTERNATE)> _ Dim cAlternate As String End Structure Quote
Administrators PlausiblyDamp Posted June 23, 2006 Administrators Posted June 23, 2006 Try _ Private Shared Function FindFirstFileW _ (ByVal lpFileName As String, ByRef lpFindFileData As WIN32_FIND_DATA) As Integer End Function for the declaration and you should be able to call it like hSearch = FindFirstFileW(Path & "*", WFD) Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
Howard Kaikow Posted June 23, 2006 Author Posted June 23, 2006 Thanx. I should have caught that. Quote
Recommended Posts