I'm having a problem with using FileSystemObject.CopyFile. I think I'm using it correctly, from the forums I've read, but I am still getting the following compiler error:
ArgumentException was unhandled: Value does not fall within expected range
Here is the code:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim fso As New Scripting.FileSystemObject
Dim testfolderchk
testfolderchk = Dir("C:\Test\")
Dim inforeader As System.IO.FileInfo
Dim filedestinationcheck = Dir("C:\Test2\")
If testfolderchk <> "" Then
If Microsoft.VisualBasic.Left(testfolderchk, 4) = "test" Then
inforeader = My.Computer.FileSystem.GetFileInfo("C:\Test" & testfolderchk)
filetime = (inforeader.LastWriteTime)
If testfolderchk = filedestinationcheck Then GoTo skipfile
If testfolderchk = filedestinationcheck2 Then GoTo skipfile
Else : GoTo skipfile
End If
End If
fso.CopyFile(testfolderchk, filedestinationcheck, True)
As suggested in the comments you should scrap the use of FileSystemObject and use instead the System.IO namespace, specifically FileInfo:
Provides properties and instance methods for the creation, copying, deletion, moving, and opening of files, and aids in the creation of FileStream objects. This class cannot be inherited.
With FileInfo you can use the method CopyTo (String, Boolean):
Copies an existing file to a new file, allowing the overwriting of an existing file.
I have drafted up a bit of code to show you what I mean:
Dim folderToCheck As String = "C:\Test"
Dim destinationFolder As String = "C:\Test2"
Dim file As IO.FileInfo = New IO.FileInfo(IO.Path.Combine(folderToCheck, "test.txt"))
Dim filetime As Date = file.LastWriteTime
file.CopyTo(IO.Path.Combine(destinationFolder, file.Name), True)
Note the use of Path.Combine:
Combines two strings into a path.
Related
My client has some internet shortcuts (*.url) on his desktop and I want to get their URL through a VB application and use them as variables.
Any idea how can I do that?
There's a sample on MSDN for *.lnk and *.appref-ms-files.
But seems to work for *.url-files too.
Quote from the site:
To check if a file is a shortcut and to resolve a shortcut path, the
COM Library Microsoft Shell Controls And Automation is used. This
library is added to the References of the Visual Studio project.
Code:
Public Function IsShortcut(strPath As String) As Boolean
If Not File.Exists(strPath) Then
Return False
End If
Dim directory As String = Path.GetDirectoryName(strPath)
Dim strFile As String = Path.GetFileName(strPath)
Dim shell As Shell32.Shell = New Shell32.Shell()
Dim folder As Shell32.Folder = shell.NameSpace(directory)
Dim folderItem As Shell32.FolderItem = folder.ParseName(strFile)
If folderItem IsNot Nothing Then
Return folderItem.IsLink
End If
Return False
End Function
Public Function ResolveShortcut(strPath As String) As String
If IsShortcut(strPath) Then
Dim directory As String = Path.GetDirectoryName(strPath)
Dim strFile As String = Path.GetFileName(strPath)
Dim shell As Shell32.Shell = New Shell32.Shell()
Dim folder As Shell32.Folder = shell.NameSpace(directory)
Dim folderItem As Shell32.FolderItem = folder.ParseName(strFile)
Dim link As Shell32.ShellLinkObject = folderItem.GetLink
Return link.Path
End If
Return String.Empty
End Function
I am trying to search if a text file in a sub-folder exists.
This is the code I am using:
'Checks the program's root folder to see if the root folder exists.
Dim FolderName = New DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Cake Orders\" & TextBox1.Text))
Dim McKnwoll As String = Path.Combine(FolderName.FullName, Trim(TextBox2.Text) & (" ") & Trim(TextBox3.Text) + ".RTO")
If Not McKnwoll.Exists Then
‘Message to user that file does not exist in sub-folder
Else
‘Message to user that file does exists in sub-folder
End If
I am getting an error that 'Exists' is not a member of 'String'. How can I re-work my code to check if the text file whose name is in the format of "TextBox2.Text & (" ") & TextBox3.Text + ".RTO"; exists.
I am using Visual Basic 2010 Express. Thank you.
File.Exists returns a Boolean indicating whether a file at a certain path exists:
If File.Exists(pathToFile) Then
...
End If
Be sure to include Imports System.IO at the top of your source code file.
You seem quite new in programming. Welcome.
That error message you got ('Exists' is not a member of 'String') tells you exactely what is wrong: You try to ask a string (some text) whether it exists, but what you like to do is to ask a file whether it exists.
The class that provides information about a file is called "FileInfo", and FileInfo has an "Exists" property that you can call:
Dim myFileInfo As New FileInfo(McKnwoll)
If myFileInfo.Exists Then
'do something
End If
That's the object oriented answer, Heinzi's more service oriented one but works, of course, too.
There have been several other small issues I noticed with your code, e.g.
"Cake Orders\" & TextBox1.Text
does not use Path.Combine but makes a string concatenation using fix a "\" as directory separater. Or that the DirectoryInfo is not really used here, the string to the folder is enough.
You also try to handle 3 different issues (reading the values from the user interface, constructing the fullname of the file, checking whether the file exists) in one single code block. I would split them into 3 different ones (actually 4, I would add another one for displaying error messages).
Your simple few lines of codes could be complicated like this ;-)
Imports System.IO
Imports System.Text
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ReadFileIfPossible(TextBox1.Text, TextBox2.Text, TextBox3.Text)
End Sub
Private Sub ReadFileIfPossible(subfolder As String, part1 As String, part2 As String)
'Get the path to the RTO file
Dim myFilePath As String = Nothing
Try
myFilePath = GetRtoFilePath(subfolder, part1, part2)
Catch ex As Exception
DisplayErrorMessage("Error constructing file name! Please check the values of TextBox1, TextBox2 and TextBox3.")
Return
End Try
'Get the file info
Dim myFile As FileInfo = Nothing
Try
myFile = New FileInfo(myFilePath)
Catch ex As Exception
DisplayErrorMessage(ex.Message)
Return
End Try
'Check whether it exists
Dim myExists As Boolean = False
Try
myExists = myFile.Exists 'it's IO, everything might throw an exception...
Catch ex As Exception
DisplayErrorMessage(ex.Message)
Return
End Try
'Display message if not found
If (Not myExists) Then
DisplayErrorMessage("File ""{0}"" could not be found!", myFilePath)
Return
End If
'Read the file
Dim myLines As String() = Nothing
Try
myLines = File.ReadAllLines(myFile.FullName, New UTF8Encoding(True))
Catch ex As Exception
DisplayErrorMessage(ex.Message)
Return
End Try
'Do something with it...
End Sub
Private Shared Function GetRtoFilePath(subfolder As String, part1 As String, part2 As String) As String
'Check args
If (subfolder Is Nothing) Then Throw New ArgumentNullException("subfolder")
If (part1 Is Nothing) Then Throw New ArgumentNullException("part1")
If (part2 Is Nothing) Then Throw New ArgumentNullException("part2")
'Normalize args
part1 = part1.Trim()
part2 = part2.Trim()
'Build path
Dim myDesktopPath As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Dim myFolderPath As String = Path.Combine(myDesktopPath, "Cake Orders")
myFolderPath = Path.Combine(myFolderPath, subfolder)
Dim myFileName As String = String.Format("{0} {1}.RTO", part1, part2)
Dim myResult As String = Path.Combine(myFolderPath, myFileName)
myResult = Path.GetFullPath(myResult)
'Return result
Return myResult
End Function
Private Sub DisplayErrorMessage(message As String, ParamArray args As Object())
Dim myMsg As String = String.Format(message, CType(args, Object()))
MsgBox(myMsg, MsgBoxStyle.OkOnly, "Error")
End Sub
End Class
Have fun.
I'm currently doing a project where I need to search through a specific directory for files. If the files found are not the approved extension then the files must be moved to an archive folder. I need to user to be allowed to remove and add extensions so the list is not a set size and will most likely change weekly.
So far I'm able to loop through the directories and list all the files in there into a listbox. My problem comes when trying to differentiate between the approved list and the current list and I can't narrow down the files and display them in the list box.
My error is : 'An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll' where my 'list1' variable count is 0 because no children were found even when there are matching approved data and current data.
Any help would be appreciate from stack overflow community! Thanks!!
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim list1 As List(Of String)
list1 = (From item As String In Me.ListBox1.Items Select item Where Me.ListBox1.Items.Contains(Me.lstApprovedItems.Items)).ToList()
ListBox1.Items.Add(list1(0))
End Sub
Dim fri As FileInfo
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim FileName1 As String = ""
Dim dir2 As New DirectoryInfo("D:\Administrator\Desktop\File Management System v0.2\File Management System\File Directories\File Directories\00000000.00F")
Dim dir1 As DirectoryInfo() = dir2.GetDirectories()
Dim fri2 As DirectoryInfo
For Each fri2 In dir1
FileName1 = Convert.ToString(fri2.Name)
Dim dir As New DirectoryInfo("D:\Administrator\Desktop\File Management System v0.2\File Management System\File Directories\File Directories\00000000.00F\" + FileName1)
Dim fiArr As FileInfo() = dir.GetFiles()
For Each Me.fri In fiArr
ListBox1.Items.Add(fri.Name)
Next fri
Next
End Sub
End Class
There are several ways to go about this, this way is similar to what you have.
' first get OK extension into an array (or list)
Dim Auth(lbAuthExt.Items.Count - 1) As String
lbAuthExt.Items.CopyTo(Auth, 0)
' storage for the result
' only save the Authorized ones if that is all you care about
Dim AuthList As New List(Of FileInfo)
Dim NoAuthList As New List(Of FileInfo)
Dim dir = New DirectoryInfo("C:\Temp")
For Each fi As FileInfo In dir.GetFiles
If Auth.Contains(fi.Extension) Then
AuthList.Add(fi)
Else
NoAuthList.Add(fi)
End If
Next
I am saving FileInfo because (presumably) you might display the names to the user without all the redundant path info. But your code will need the full path name for later Copy/Move ops.
' set the list as the datasource
lbResult.DataSource = AuthList
' display file name
lbResult.DisplayMember = "Name"
' return full name to code
lbResult.ValueMember = "FullName"
The code can of course simply loop on AuthList to do its job. If you need to show the results to the user first, there is no need to make 2 copies. DisplayMember is used to tell the ListBox which property value to display while retaining all the other info in the list.
Finally, a linq version which simply saves the full file name:
Dim myAuthList = (From func In Directory.EnumerateFiles("C:\Temp", "*.*",
System.IO.SearchOption.AllDirectories)
Where Auth.Contains(Path.GetExtension(func),
StringComparer.InvariantCultureIgnoreCase)).ToList
I have been asked to create a console application which polls an active Directory. (C.\Temp\Input)
When a file comes in with (filename).SUCCESS, filename is retrieve in order to run a SQL query. So
IF fileextension = SUCCESS
Runs SQL Query using filename to change a value in the SQL Table.
Moves Original file to c:\temp\Input\Processed
Any help or hints would be much appreciated.
UPDATED:
Hi, With a few looks at various sites iv come up with the below. Forgetting the SQL for now, im only after the Filename and the moving of files but im getting an IO Exception that the file is already in use:
Imports System.IO
Imports System.String
Module Module1
Dim fileName As String = "C:\temp\Input\NR12345.success"
Dim pathname As String = "C:\temp\Input\"
Dim result As String
Dim sourceDir As String = "C:\temp\Input\"
Dim processedDir As String = "C:\temp\Input\Processed\"
Dim fList As String() = Directory.GetFiles(sourceDir, "*.success")
Sub Main()
result = Path.GetFileName(fileName)
Console.WriteLine("GetFileName('{0}') returns '{1}'", fileName, result)
result = Path.GetFileName(pathname)
Console.WriteLine("GetFileName('{0}') returns '{1}'", pathname, result)
Call MySub()
End Sub
Sub MySub()
'Move Files
For Each f As String In fList
'Remove path from the file name.
Dim fName As String = f.Substring(sourceDir.Length = 0)
Dim sourceFile = Path.Combine(sourceDir, fName)
Dim processedFileDir = Path.Combine(processedDir, fName)
' Use the Path.Combine method to safely append the file name to the path.
' Will overwrite if the destination file already exists.
File.Copy(Path.Combine(sourceDir, fName), Path.Combine(processedDir, fName), True)
'File.Copy(sourceFile, processedFileDir)
Next f
End Sub
End Module
I've used this before:
The FileWather Class
Really useful for polling directories for changes in structure and file details etc.
You can then use this to get an extension of a file and, if it meets your criteria, perform some actions.
These links come with examples so enjoy!!
Sub MySub()
'Move Files
For Each f As String In fList
Dim fInfo As FileInfo = New FileInfo(f)
Dim fName As String = fInfo.Name
Dim processedFileDir = Path.Combine(processedDir, fName)
' Use the Path.Combine method to safely append the file name to the path.
' Will overwrite if the destination file already exists.
File.Copy(fInfo.FullName, processedFileDir, True)
Next f
End Sub
I want to store a unicode string in a flat file on a windows box from an excel/vba macro. The macro converts normal string to unicode representation, need to store it in a file and retrieve later.
As mentioned, you can use the Microsoft Scripting Runtime (scrrun.dll). I have posted some examples below. Some people also like the native file IO features. There is an extensive (and fairly comprehensive thread) thread here: http://www.xtremevbtalk.com/showthread.php?t=123814
However for Unicode files it's probably the least painful to use Textstreams:)
Public Sub StringToTextFile(ByVal path As String, ByVal value As String)
'Requires reference to scrrun.dll
Dim fso As Scripting.FileSystemObject
Dim ts As Scripting.TextStream
Set fso = New Scripting.FileSystemObject
Set ts = fso.CreateTextFile(path, False, True)
ts.Write value
ts.Close
End Sub
Public Sub LazyMansWay(ByVal path As String, ByVal value As String)
'Reference counting will cause the objects to be destroyed. The termination
'events of the classes will cause the connections to be closed.
CreateObject("Scripting.FileSystemObject").CreateTextFile(path, False, True).Write value
End Sub
Add a reference to "Microsoft Scripting Runtime" COM component (scrrun.dll).
It has all the classes (specifically FileSystemObject/TextStream) to create/read/write files.
The best solution I could figure is read the string in to a byte array and write each byte to a binary file
Private Function WriteBinaryFile(ByRef szData As String)
Dim bytData() As Byte
Dim lCount As Long
bytData = szData
Open PwdFileName For Binary As #1
For lCount = LBound(bytData) To UBound(bytData)
Put #1, , bytData(lCount)
Next lCount
Close #1
End Function
Read it back by opening the file in binary mode and reading each byte into a byte array and then converting it to a string.
Sub ReadBinaryFile(ByRef gszData As String)
Dim aryBytes() As Byte
Dim bytInput As Byte
Dim intFileNumber
Dim intFilePos
intFileNumber = FreeFile
Open PwdFileName For Binary As #intFileNumber
intFilePos = 1
Do
Get #intFileNumber, intFilePos, bytInput
If EOF(intFileNumber) = True Then Exit Do
ReDim Preserve aryBytes(intFilePos - 1)
aryBytes(UBound(aryBytes)) = bytInput
intFilePos = intFilePos + 1
Loop While EOF(intFileNumber) = False
Close #intFileNumber
gszData = aryBytes
End Sub