Better Way to Copy Move Rename File, Visual Basic (VS 2012 V11) - vb.net

I want to copy, rename, and move a file to a new location. According to http://msdn.microsoft.com/en-us/library/36xbexyf(v=vs.90).aspx the following code should do so:
This example copies the file Test.txt to the directory TestFiles2 and
renames it NewFile.txt.
My.Computer.FileSystem.CopyFile _
("C:\UserFiles\TestFiles\test.txt", _
"C:\UserFiles\TestFiles2", "NewFile.txt", FileIO.UICancelOption.DoNothing)
However, when I type this code it only sees the "NewFile.txt" parameter as the Boolean parameter that handles overwrites. I believe this is a mistake on the websites part.
If I can't use "My.Computer.FileSystem.CopyFile" (unless I am doing something wrong) to copy rename and move a file, is there a better way then this:
' Rename the file to be copied the name you want it to be in the new location
My.Computer.FileSystem.RenameFile("C:\OriginalFile.txt", "OriginalFileTemporaryName.txt")
' Copy the file to the new location and overwrite if it exists there
My.Computer.FileSystem.CopyFile ("C:\OriginalFileTemporaryName.txt", "C:\UserFiles\TestFiles2", True)
' Rename the original file back to it's original name
My.Computer.FileSystem.RenameFile("C:\OriginalFileTemporaryName.txt", "OriginalFile.txt")
The problem I have with the above is that I might end up renaming the original file a temporary name that already exists in the original files location. I want to avoid that. I also do not want to rename the copied file in the destination folder because I do not see an option to force an overwrite for "My.Computer.FileSystem.RenameFile"
Is this even a half decent solution?
Is there not a better way to do this?

I think you have syntax error. You are trying to give the target file name as two parameters - directory name and file name, when you should give both as one string.
My.Computer.FileSystem.CopyFile ("C:\UserFiles\TestFiles\test.txt", "C:\UserFiles\TestFiles2\NewFile.txt")
Like that. Third parameter could be boolean (True/False) - whether or not you wouldd like to overwrite the target file if it exists.
If you want to first check whether the file exists, take a look at System.IO.File class, it has "Exists" method, which accepts file name and returns boolean. It has also methods to manipulate files which you can use instead of FileSystem class, although there is no performance advantage.

It certainly looks like a mistake on the website. That shouldn't stop us, though; just put the directory and filename into the same parameter:
My.Computer.FileSystem.CopyFile("C:\UserFiles\TestFiles\test.txt", "C:\UserFiles\TestFiles2\NewFile.txt", FileIO.UICancelOption.DoNothing)
(If you want to force an overwrite, change the third parameter to True. I don't know that you can overwrite and pass CancelOption.DoNothing in the same call.)

Related

VB.NET file filter

I want get the oldest creation file in a directory but want to exclude the file ‘Startup’(Which is currently the oldest file). So I would like to skip that file and get the next oldest creation file in the directory which would be ‘TEST’.
This code only gets the Startup.
Dim oldestFile = folderlist.OrderBy(Function(fi) fi.CreationTime).First
1:
You use the Where function to filter.
Dim folder As New DirectoryInfo(folderPath)
Dim oldestFile = folder.EnumerateFiles().
Where(Function(fi) fi.Name <> "Startup.txt").
OrderBy(Function(fi) fi.CreationTime).
First()
Note that it is preferable to use EnumerateFiles rather than GetFiles unless you really want access to the full array of files after the fact. If you only need that one file, EnumerateFiles is better because it doesn't get all the files first and then perform the other operations on that array. You may already know this but most people don't at first.
Note also that I'm assuming that those are text files based on the icons. Change the name in the filter if they are something else. As a developer, you really ought to switch off the File Explorer feature that hides file extensions. That's for people who don't understand computers.

How to check for any files with FileExists(String) method

I'm trying to automate a document handling process, and I need to check if there are any files inside a certain folder. The process itself removes the files from the folder once it finishes, so I need it to loop back and check if there are any files left.
So far I've been using a sample file like this:
File.Exists("C:\Users\gcaor\Desktop\OC\150.pdf")
150.pdf is the sample file it's searching for, but is there a way to search for any file at all? So that it returns true if there is a file in the folder and false if there isn't
You can use Directory.EnumerateFiles + Any:
Dim anyFileExist = Directory.EnumerateFiles(path).Any()
This is using standard .NET methods and also stops at the first file found.

VBA store path including Environ("username") in a text file

I am trying to create a text file that stores a folder path. This text file is then referenced via a vba sub. The path I want to use is something like:
"C:\Users\" & Environ("username") & "\AppData\Roaming\Microsoft\Templates"
This works fine in the sub but I've tried all kinds of variations in the text file but none of them get recognised and trigger error 52 - bad file.
Is there a way to make this work? I'm trying to allow people to set a different file path without needing to modify the code.
If you are trying to provide a path to the folder where user templates are stored then you could try
ActiveDocument.AttachedTemplate.Path
as an alternative (returns the path to the folder where the current template is stored for the user).
Otherwise store the path template as something like
"C:\Users\###UserName###\AppData\Roaming\Microsoft\Templates"
Which gives you a single string to retrieve. Then you can use the VBA Replace function to change the ###UserName### to the value of Environ("UserName)"
my_user_path = replace(my_path_template, Environ$("UserName"))
You might also want to explore using either a CustomDocumentProperty, or a Variables, to store your path template as this keeps the path template string as part of the Document or Template and not in a separate file.

Copy and Delete File Leaves Zero Length File at Source

I'm trying to copy a file from one directory to another. After the copy, I want to delete the original file. The expected result is that the source file no longer exists and the destination file does exist. The actual result is that the destination file exists and that an empty source file exists. Watching the directory during execution, the source file initially disappears then upon exiting the program it reappears with a length of zero.
Here's sample code:
Imports System.IO
Module Module1
Sub Main()
Dim sourceFileName As String = "c:\TestDir\source\TestFile.txt"
Dim destFileName As String = "c:\TestDir\destination\TestFile.txt"
System.IO.File.Copy(sourceFileName, destFileName)
System.IO.File.Delete(sourceFileName)
End Sub
End Module
If I were to remove the System.IO.Copy, the zero-length file does not appear. So it seems to have something to do with the combination of copying and deleting.
Are my expectations amiss? I realize I can delete the destination if it exists then Move the file, but I would like to understand why my sample does not work as I expect it. Thanks for any insight.
Try using the FileSystem.DeleteFile method from here:
https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.fileio.filesystem.deletefile?view=netframework-4.7.2
This should completely remove the file.
Has the Read-Only attribute been applied to your test file? If so, you can try something like this:
File.Copy(sourceFileName, destFileName)
File.SetAttributes(sourceFileName, FileAttributes.Normal);
File.Delete(sourceFileName)
Is there a reason you're not just using File.Move?

Either correct VB6/DOS/SQL function or suggest better alternative

I am currently reprogramming code made long ago by a less than skilled programmer. Granted the code works, and has for a number of years but it is not very efficient.
The code in question is in VB6 with SQL calls and it checks a particular directory on the drive (in this example we will use c:\files) and if a file exists, it moves the file to the processing directory loads the parameters for that particular file and processes them accordingly.
Currently the code uses the DIR function in VB6 to identify a file in the appropriate directory. The only problem is that if a number of files exist in the directory it is a crap shoot as to if it will grab the 5kb file and process it in 3 seconds or if it will grab the 500,000kb file and not process any others for the next 10 minutes.
I search many message boards to find some way to have it pick the smallest file and found I could build a complicated array to perform something similar to a sort but I decided to try alternate ideas instead to hopefully reduce processing time involved. Using ancient DOS knowledge I created something that should work, but for some reason is not (hence posting here).
I made a batch file that we will call c:\test.bat which contained the following lines:
delete c:\test.txt
dir /OS /B c:\files\*.txt>c:\test.txt
This deletes a prior existence of test.txt the pipes a directory without headers sorted by file size smallest to largest into c:\test.txt.
I then inserted the following code into the pre-existing code at the beginning:
Shell "c:\test.bat", vbHide
filepath = "c:\test.txt"
Open filepath For Input As #1
Input #1, filegrabber
Close #1
When I step through the code I can see that this works correctly, except now later on in the code I get a
Runtime error 91 Object variable or with block variable not set
in regard to assigning a FileSystemObject. Am I correct in guessing that FSO and Shell do not work well together? Also if you can suggest a better alternative to getting the smallest file from a existing directory suggestions are appreciated.
No need for sorting.
Just use Dir() to cruise through the directory. Before the loop set a Smallest Long variable to &H7FFFFFFF then inside the loop test each returned file name using the FileLen() function.
If FileLen() returns a value less than Smallest assign that size to Smallest and assign that file name to SmallestFile a String variable.
Upon loop exit if Smallest = &H7FFFFFFF there were no files, otherwise SmallestFile has your file name.
Seems incredibly simple, what am I missing?
Another approach is to use the FileSystemObject's Files collection. Just iterate the files collection for a given folder and evaluate each File object's Size property. So long as you don't have a million files in a folder or something, performance should be fine.