Newbie question re vb.net and iterating files

M

MarceepooNu

I am a newbie learning VB.net.
I have spent a few days, unsuccessfully trying to figure out how to modify
the code below so that I could get a list of:
(1) all the .bat files in the root directory: "E:\â€, and
(2) all the .bat files in the root directory: "E:\†and all directories
under it.

Here's the code I copied the code below from a help file:
For Each foundFile As String In My.Computer.FileSystem.GetFiles _
(My.Computer.FileSystem.SpecialDirectories.MyDocuments)
sfilelist = sfilelist & vbCrLf & CStr(foundFile)
'ListBox1.Items.Add(foundFile)
Next
MsgBox(sfilelist)


Could anyone show me how tom odify that code so that I could get a list of:
(1) all the .bat files in the root directory: "E:\â€, and
(2) all the .bat files in the root directory: "E:\†and all directories
under it?
....and tell me where I could find information about that?

At the risk of appearing greedy:
(3) Is there a simple way to give such a search "administrative rights"
(I hope I am using these terms correctly)
so that I could run a search for all .bat files on the C drive?

Thanks in advance for any help you have time to give.
Marceepoonu

p.s. I erroneously posted this in the wrong discucssion group a few days
ago, and was told by a kind person (who answered it) to re-post it here.
 
J

James Hahn

The following fragment will copy matching files into listbox 1 and all
subfolders into listbox2.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
GetFolderFiles(My.Computer.FileSystem.SpecialDirectories.MyDocuments)
End Sub

Sub GetFolderFiles(ByVal Folder)
Dim di As New System.IO.DirectoryInfo(Folder)
For Each fi As System.IO.FileInfo In di.GetFiles("*.BAT")
ListBox1.Items.Add(fi.FullName)
Next
For Each FoundFolder In di.GetDirectories
Try
ListBox2.Items.Add(FoundFolder.FullName)
GetFolderFiles(FoundFolder.FullName)
Catch
MsgBox("Error accessing folder " & FoundFolder.FullName)
End Try
Next
End Sub
 
A

Armin Zingler

MarceepooNu said:
I am a newbie learning VB.net.
I have spent a few days, unsuccessfully trying to figure out how to
modify the code below so that I could get a list of:
(1) all the .bat files in the root directory: "E:\â€, and
(2) all the .bat files in the root directory: "E:\†and all
directories under it.

Here's the code I copied the code below from a help file:
For Each foundFile As String In My.Computer.FileSystem.GetFiles _
(My.Computer.FileSystem.SpecialDirectories.MyDocuments)
sfilelist = sfilelist & vbCrLf & CStr(foundFile)
'ListBox1.Items.Add(foundFile)
Next
MsgBox(sfilelist)


Could anyone show me how tom odify that code so that I could get a
list of:
(1) all the .bat files in the root directory: "E:\â€, and

Dim files = IO.Directory.GetFiles("e:\", "*.bat")
(2) all the .bat files in the root directory: "E:\†and all
directories under it?

Recursion is the key: (untested)

Private Shared Sub CollectBatchFiles( _
ByVal Directory As IO.DirectoryInfo, _
ByVal Collection As List(Of IO.FileInfo))

Collection.AddRange(Directory.GetFiles("*.bat"))

For Each SubDir In Directory.GetDirectories
CollectBatchFiles(SubDir, Collection)
Next

End Sub

Call:
Dim BatFiles As New List(Of IO.FileInfo)

CollectBatchFiles(New IO.DirectoryInfo("e:\"), BatFiles)


...and tell me where I could find information about that?

At the risk of appearing greedy:
(3) Is there a simple way to give such a search "administrative
rights" (I hope I am using these terms correctly)
so that I could run a search for all .bat files on the C drive?

Thanks in advance for any help you have time to give.
Marceepoonu

Search for "Impersonation". I'm afraid, I don't have an example handy. Only
found it via good old pInvoke (LogonUser), and I don't know if there's an
equivalent in the Framework.


Armin
 
M

MarceepooNu

Dear James:

Thank you. I'm going to try to use what you and Armin Zingler posted.
But, while you're (hopefully) still at your computer, I thought I should
tell you that the biggest problem that (I'm aware) I'm having is:
I can't figure out how to select the root of the e: drive as the
directory from which to extract file info,
.... instead of the ".SpecialDirectories.MyDocuments" directory that appears
in all of the examples I have found in the MSDN urls.

I feel kind of stupid for not being able to modify the code to search the
root directory of e: instead of ".SpecialDirectories.MyDocuments", but I
can't figure it out, and I've spend days trying.

Thanks for the input.

marc
 
J

James Hahn

Just replace
GetFolderFiles(My.Computer.FileSystem.SpecialDirectories.MyDocuments)
with
GetFolderFiles("E:\")

Also,
Sub GetFolderFiles(ByVal Folder)
should be
Sub GetFolderFiles(ByVal Folder As String)
That change would have made the process a little clearer. The function
simply needs the name of the top-level folder.
 
M

Michel Posseth

Armin Zingler said:
Dim files = IO.Directory.GetFiles("e:\", "*.bat")


Recursion is the key: (untested)

Private Shared Sub CollectBatchFiles( _
ByVal Directory As IO.DirectoryInfo, _
ByVal Collection As List(Of IO.FileInfo))

Collection.AddRange(Directory.GetFiles("*.bat"))

For Each SubDir In Directory.GetDirectories
CollectBatchFiles(SubDir, Collection)
Next

End Sub

Call:
Dim BatFiles As New List(Of IO.FileInfo)

CollectBatchFiles(New IO.DirectoryInfo("e:\"), BatFiles)




Search for "Impersonation". I'm afraid, I don't have an example handy.
Only
found it via good old pInvoke (LogonUser), and I don't know if there's an
equivalent in the Framework.


Armin


I also couldn`t find a good working equivalant in the framework in the past
, so i wrapped it all in a nice class

#### CLASS CODE ######

'Michel Posseth 10-07-2008
Imports System.Security
Imports System.Security.Principal
Imports System.Runtime.InteropServices
Public Class ImpersonateSpecificUser
Implements IDisposable
Private Const LOGON32_LOGON_INTERACTIVE As Integer = 2
Private Const LOGON32_PROVIDER_DEFAULT As Integer = 0
Private impersonationContext As WindowsImpersonationContext
Declare Function LogonUserA Lib "advapi32.dll" (ByVal lpszUsername As
String, _
ByVal lpszDomain As String, _
ByVal lpszPassword As String, _
ByVal dwLogonType As Integer, _
ByVal dwLogonProvider As Integer, _
ByRef phToken As IntPtr) As Integer

Declare Auto Function DuplicateToken Lib "advapi32.dll" ( _
ByVal ExistingTokenHandle As IntPtr, _
ByVal ImpersonationLevel As Integer, _
ByRef DuplicateTokenHandle As IntPtr) As Integer

Declare Auto Function RevertToSelf Lib "advapi32.dll" () As Long
Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As
IntPtr) As Long
Public Event eSpecificUserImpersonation(ByVal Success As Boolean)
Private _Impersonated As Boolean
''' <summary>
''' Gets or sets a value indicating whether this <see
cref="ImpersonateSpecificUser" /> is impersonated.
''' </summary>
''' <value><c>true</c> if impersonated; otherwise, <c>false</c>.</value>
Public Property Impersonated() As Boolean
Get
Return _Impersonated
End Get
Private Set(ByVal value As Boolean)
_Impersonated = value
End Set
End Property
''' <summary>
''' Initializes a new instance of the <see
cref="ImpersonateSpecificUser" /> class.
''' </summary>
''' <param name="UserName">Name of the user.</param>
''' <param name="Password">The password.</param>
''' <param name="Domain">The domain.</param>
Public Sub New(ByVal UserName As String, ByVal Password As String, ByVal
Domain As String)
If impersonateValidUser(UserName, Domain, Password) Then
'Insert your code that runs under the security context of a
specific user here.
RaiseEvent eSpecificUserImpersonation(True)
Else
'Your impersonation failed. Therefore, include a fail-safe
mechanism here.
RaiseEvent eSpecificUserImpersonation(False)
End If
End Sub
''' <summary>
''' Impersonates the valid user.
''' </summary>
''' <param name="userName">Name of the user.</param>
''' <param name="domain">The domain.</param>
''' <param name="password">The password.</param>
''' <returns></returns>
Private Function impersonateValidUser(ByVal userName As String, ByVal
domain As String, ByVal password As String) As Boolean
Dim tempWindowsIdentity As WindowsIdentity
Dim token As IntPtr = IntPtr.Zero
Dim tokenDuplicate As IntPtr = IntPtr.Zero
impersonateValidUser = False

If RevertToSelf() Then
If LogonUserA(userName, domain, password,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, token) <> 0 Then
If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then
tempWindowsIdentity = New
WindowsIdentity(tokenDuplicate)
impersonationContext = tempWindowsIdentity.Impersonate()
If Not impersonationContext Is Nothing Then
impersonateValidUser = True
End If
End If
End If
End If
If Not tokenDuplicate.Equals(IntPtr.Zero) Then
CloseHandle(tokenDuplicate)
End If
If Not token.Equals(IntPtr.Zero) Then
CloseHandle(token)
End If
End Function
''' <summary>
''' Undoes the impersonation.
''' </summary>
Public Sub undoImpersonation()
impersonationContext.Undo()
Impersonated = False
End Sub
#Region " IDisposable Support "
Private disposedValue As Boolean = False ' To detect redundant
calls
' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: free other state (managed objects).
End If
If Impersonated Then 'wees er zeer van dat we weer in een
normale context draaien
undoImpersonation()
End If
' TODO: free your own state (unmanaged objects).
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub


' This code added by Visual Basic to correctly implement the disposable
pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal
disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
''' <summary>
''' Impersonates the specific user_e specific user impersonation.
''' </summary>
''' <param name="Success">if set to <c>true</c> [success].</param>
Private Sub ImpersonateSpecificUser_eSpecificUserImpersonation(ByVal
Success As Boolean) Handles Me.eSpecificUserImpersonation
Me.Impersonated = Success
End Sub
End Class


#### END CLASS CODE ####



### USAGE ###


Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Using UImp As New
ista.security.UserImpersonate.ImpersonateSpecificUser("Username",
"'Password", "Domain")
MsgBox(UImp.Impersonated)
'if above msgbox returned true
'all code in the using block will be run in the context of the impersonated
user
' so for instance shares are accessible that are normally only accessible
to that user , and you have the rights in these shares of that user etc etc
' the code is thoroughly tested in my company and is in unmodified form in
use in a win 2000 , 2003 , 2008 active directory domain with XP and Vista
clients



End Using



End Sub
End Class



regards

Michel Posseth
 
A

Armin Zingler

Michel said:
I also couldn`t find a good working equivalant in the framework in
the past , so i wrapped it all in a nice class

Thanks. The example I mentioned (only for the sake of completeness for the
OP):
http://www.gssg.de/
Visual Basic -> VB.Net -> "Impersonate / Benutzerwechsel" (German, but the
Code is English ;-) )


Armin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top