RenameFile doubles the extension on some computers - vb.net

I have a simple Project running on two computers independently. It renames a bunch of files and uploads them via ftp (FluentFTP). On my development computer this works ok
img00012.jpg -> myPicture_001_summer.jpg
img00014.jpg -> myPicture_002_summer.jpg
img00015.jpg -> myPicture_003_summer.jpg
img00018.jpg -> myPicture_004_summer.jpg
on the other one it doubles the file extensions
img00012.jpg -> myPicture_001_summer.jpg.jpg
img00014.jpg -> myPicture_002_summer.jpg.jpg
img00015.jpg -> myPicture_003_summer.jpg.jpg
img00018.jpg -> myPicture_004_summer.jpg.jpg
The code I am using is essentially this:
Dim filesToCopy As New Dictionary(Of String, List(Of String))
For Each fil In files
dim ftpFolder = calcFtpFolder(fil) 'returns e.g. "/mySubFolder/"
dim newName = calcNewName(fil, nbr) 'returns e.g. "myPicture_001_summer"
My.Computer.FileSystem.RenameFile(fil.FullName, newName + fil.Extension)
filesToCopy(ftpFolder).Add(fil.DirectoryName + "\" + newName + fil.Extension)
Next fil
For Each kvp In filesToCopy
Dim filelist = kvp.Value
Dim remoteDir = kvp.Key
ftp.UploadFiles(filelist, remoteDir, .....)
Next
Both computers run on an updated windows10x64. Has anyone encountered similar things? Where should I investigate?

Probably both are like this: img00012.jpg -> myPicture_001_summer.jpg.jpg, because you have checked the "Hide extensions for known files" in one of the computers.
So, open a Windows Explorer > See/View > Options > See/View > Hide Extensions for known files (could be a little different, my language is not EN).

Related

How to read files in folders?

I am trying to get my application to check for folders in the folderbrowserdialogs selectedpath and then get those files, but it doesn't work I have tried both listed ways below. The second way gives me an error: (Expression is of type char which is not a collection type)
For Each folder In FileBrowserDialog.SelectedPath
Dim counter As _
System.Collections.ObjectModel.ReadOnlyCollection(Of String)
counter = My.Computer.FileSystem.GetFiles(folder)
Label1.Text = counter.Count.ToString
Next
For Each folder In FileBrowserDialog.SelectedPath
Dim counter As _
System.Collections.ObjectModel.ReadOnlyCollection(Of String)
For Each foundfile In folder
counter = My.Computer.FileSystem.GetFiles(foundfile)
Label1.Text = counter.Count.ToString
Next
Any help is appreciated.
FolderBrowserDialog1.SelectedPath will return the path the user selected in the dialog. You still need to write code to go get the files. There may not be a need to get the folders and then files in them. Net has ways to do that for you:
FolderBrowserDialog1.ShowDialog()
Dim myPath As String = FolderBrowserDialog1.SelectedPath
' get all files for a folder
Dim files = Directory.GetFiles(myPath)
' get all files for all sub folders
Dim files = Directory.GetFiles(myPath, "*.*",
System.IO.SearchOption.AllDirectories)
' get certain file types for folder and subs
Dim files = Directory.GetFiles(myPath, "*.jpg",
System.IO.SearchOption.AllDirectories)
You also are not going to be able to simply assign the results to a ReadOnlyCollection like that, because they are ReadOnly. The collection needs to be created/instanced with the complete list:
Dim counter As new ReadOnlyCollection(Of String)(files)

How to find or get files in Directory with Specific word in the file name Visual Basic.net?

I need to get files from a directory containing specific characters in it's name:
The following code below will return any file with the .csv extension. The problem is there are other csv file I need to leave alone or not get.
Dim FileLocation As DirectoryInfo = _
New DirectoryInfo("C:\Folder\Subfolder\Data\Input\")
Dim fi As FileInfo() = FileLocation.GetFiles("*.csv")
Instead of getting any csv file, I would like to get a file with the word data, so any file name containing the word data. Example: *my_data_file.csv*
How do I do this with the code above?
You can update the filter with the string you want to account for (caps will automatically be taken care of):
Dim fi As FileInfo() = FileLocation.GetFiles("*data*.csv")
In any case, bear in mind that this filtering is not "too accurate". For example, the code above would also account for any file (including "data"), whose extension includes csv (e.g., *.csva, *.csvb, etc.). If you want a 100%-reliable approach you should better set up a loop and carry out the filtering "manually"; loops are pretty fast and you wouldn't even notice the difference.
Example of a loop:
Dim fi As List(Of FileInfo) = New List(Of FileInfo)
For Each File In FileLocation.GetFiles()
If (File IsNot Nothing) Then
If (Path.GetExtension(File.ToString.ToLower) = ".csv") Then
If (File.ToString.ToLower.Contains("data")) Then fi.Add(File)
End If
End If
Next
This code will work for sure under your exact requirements and might take care of more complex requests. I have accounted for a List just to show the point clearer.
If you can use LINQ extensions then you can do it this way:
' Get Files {directory} {recursive} {ext} {word in filename}
Private Function Get_Files(ByVal directory As String, _
ByVal recursive As IO.SearchOption, _
ByVal ext As String, _
ByVal with_word_in_filename As String) As List(Of IO.FileInfo)
Return IO.Directory.GetFiles(directory, "*" & If(ext.StartsWith("*"), ext.Substring(1), ext), recursive) _
.Where(Function(o) o.ToLower.Contains(with_word_in_filename.ToLower)) _
.Select(Function(p) New IO.FileInfo(p)).ToList
End Function
Usage example:
For Each file As IO.FileInfo In Get_Files("C:\Folder\Subfolder\Data\Input\", _
IO.SearchOption.TopDirectoryOnly, _
"csv", _
"data")
MsgBox(file.Name)
Next
Replace the wildcard search below "." with your search criteria, for example you want all files that start with name "Hospital*"
Dim Folder As New IO.DirectoryInfo("C:\SampleFolder")
For Each File as IO.FileInfo in Folder.GetFiles("*.*",IO.SearchOption.AllDirectories)
ListBox1.Items.Add(File.FullName)
Next
I would have added this as a comment to the accepted answer, but I do not have enough points to do so:
I just wanted to add varocarbas's answer that, if anyone was wondering (as I was) if this would work in a web scenario as well, it will. Just place the web path inside Server.MapPath() like this:
Dim FileLocation As DirectoryInfo =
New DirectoryInfo(Server.MapPath("/Folder/SubFolder/Data/Input/"))
NOTE: Will NOT work with full url's (no 'http://www.123.com').
Dim Folder As New IO.DirectoryInfo("C:\SampleFolder")
For Each File as IO.FileInfo in Folder.GetFiles("*.*",IO.SearchOption.AllDirectories)
ListBox1.Items.Add(File.FullName)
Application.DoEvents()
Next

VB.net express System.UnauthorizedAccessException

I am trying to write a file listing custom class in VB.net 2010 express on a Win7 64 bit machine. I installed VB.net express using an account that has administrator rights on both the machine and the network it belongs to. I should be able to access any file on the machine and from Windows Explorer, I can. I have been stopped cold by a “System.UnauthorizedAccessException”.
I have tried changing the manifest file. Although that should not be needed since the account already has full permissions. It has not worked. Below is a fragment of the offending code.
I am beginning to wonder if it is possible read the files on a drive using managed code. I can revert to the VBA class that in capsules ancient Win32 API calls that I wrote years ago but that violates the purpose of this exercise. Any suggestions would be appreciated.
Private Sub sLoadCatalog(ByVal strPath As String, ByVal intParentID As Integer)
'Get the file list
Dim strsearchPattern As String = "*"
Dim fp As New FileIOPermission(FileIOPermissionAccess.PathDiscovery _
Or FileIOPermissionAccess.Read, strPath)
Try
'fp.Demand()
fp.Assert()
Dim dirInfo As DirectoryInfo = New DirectoryInfo(strPath)
Dim FileList() As FileInfo = dirInfo.GetFiles()
If FileList.Length > 0 Then
… Loop through the file list and do something exciting
End If
Dim dirFolder() As DirectoryInfo = dirInfo.GetDirectories
If dirFolder.Length > 0 Then
… Loop through the folder list and do something exciting
sLoadCatalog(strfolder, intLastID)
Else
Exit Sub
End If
Catch e As SecurityException
MessageBox.Show("Security Cannot access folder " & strPath)
Catch k As UnauthorizedAccessException
MessageBox.Show("Unauthorized Cannot access folder " & strPath)
End Try

Files that are deleted with vb and then replacements copied are still acting as old file

This is a winforms vb.net application. Because of some limitations I am not able to use the built in clickOnce updating available in VS. So to handle updates for my application i have wrote an update app. which downloads an email attachment and processes it. All works great up to and including deleting the old files from the applications install folder and then moving the updated files to that folder.
But the new files seem to not have any effect on the application at all. Just for testing I placed a MessageBox.Show in the applications Form Load event.. The app shows the messagebox in VS when I debug. As well as when I run the app from the bin folder.. When my updater app does the copying the files are there but no dice nothing is changed and no message box shows when the app loads. Further investigating the problem I manually deleted the files that are to be replaced in the application folder and then unzipped the contents of the update zip file to that folder.. Started App and now a message box shows.. If I copy the files for the app directly from the bin folder to the app folder it shows as well.
This leads me to believe that there is something going on behind the scene in the below function that I am not catching. Any ideas why this is failing???
Function ApplyUpdates(ByVal c As Integer, ByVal e As List(Of MessagePart))
Dim xxxxState As Boolean = False
Dim _path As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "\XXXX\UpdateFiles\"
Dim d As Integer = 20
xxxxState = isProcessRunning("xxxx")
If xxxxState = True Then
KillxxxxTask()
End If
For Each _S In System.IO.Directory.GetFiles(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "XXXX\UpdateFiles")
System.IO.File.Delete(_S)
Next
For Each att In e
Dim y As Boolean = UnZip(att.FileName)
Next
For Each f In System.IO.Directory.GetFiles(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "\XXXX\UpdateFiles")
Dim y As String = Path.GetExtension(f)
Dim _fNM As String = Path.GetFileNameWithoutExtension(f)
If y.Contains("ex0") Then
My.Computer.FileSystem.RenameFile(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "\XXXX\UpdateFiles" + "\" + _fNM + y, _fNM + "." + "exe")
f = f.Replace("ex0", "exe")
End If
If y.Contains("dl0") Then
My.Computer.FileSystem.RenameFile(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "\XXXX\UpdateFiles" + "\" + _fNM + y, _fNM + "." + "dll")
f = f.Replace("dl0", "dll")
End If
updating(d, "Copying File : " + f)
d += 10
Dim fName As String = Path.GetFileName(f)
Next
For Each S In System.IO.Directory.GetFiles(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "\XXXX\UpdateFiles")
Dim _ofile As String = Path.GetFileName(S)
If File.Exists("C:\XXXX\" + _ofile) Then
File.Delete("C:\XXXX\" + _ofile)
End If
' File.Copy(S, "C:\XXXX\" + _ofile, True)
Next
For Each S In System.IO.Directory.GetFiles(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "\XXXX\UpdateFiles")
Dim _ofile As String = Path.GetFileName(S)
File.Move(S, "C:\XXXX\" + _ofile)
Next
updating(100, "Update Completed")
Return Nothing
End Function
This sounds an awful lot like Windows File virtualization.
Search for the file in C:\Documents and Settings\<userName>\Application Data and subfolders, I suspect you'll find them in there.
Windows does this to protect your program from itself if you don't include an app.manifest in your project. Windows will assume your application is an old, legacy application that is not UAC aware unless it has an app.manifest. To prevent your application from crashing from denied file access, it allows the file operation to be performed, but instead secretly maps the file operation to a safe, local folder.
Just add an app.Manifest: Project Add -> New Item -> Application Manifest File
That should do it. You may find that you need to request an elevated permission, but the details are all in the app.manifest file.
For details on File Virtualization, have a look at this explanation. It's a big article, but if you Ctrl-Find 'Virtualization process' it will take you to the relevant section.
See This MSDN article for more details on the app.manifest.

VB.NET: GetFiles Method - "Access to the path 'G:\System Volume Information' is denied."

Here is my code,
Dim allFiles As FileInfo() =
tempDir.GetFiles("*.pdf", SearchOption.AllDirectories)
I've googled and found that I need to change the permissions of my app from
Project properties > View UAC Settings > and change level to level="requireAdministrator"
But its also not working. I found something about FileIOPermission class, but dont know how to implement it.
==> Detailed code.
Dim tempDir As New DirectoryInfo(path)
Dim FileDetails(4) As String
Dim iTem As ListViewItem
If (tempDir.Attributes <> FileAttributes.System) Then
Dim allFiles As FileInfo() = tempDir.GetFiles("*.pdf", SearchOption.AllDirectories)
Dim oneFIle As FileInfo
For Each oneFIle In allFiles
FileDetails(0) = oneFIle.Name()
FileDetails(1) = oneFIle.FullName()
FileDetails(2) = oneFIle.Length() / (1024 * 1024)
FileDetails(2) = FileDetails(2).Remove(5)
iTem = New ListViewItem(FileDetails)
ListView1.Items.Add(iTem)
Next
End If
Path is a string that contains the path required, in this case G:\
You won't find PDF files in this folder:
The System Volume Information folder is a hidden system folder that the System Restore tool uses to store its information and restore points. (MSDN)
So just ignore it.
Granted, GetFiles() does not allow you to ignore files/folders, so you'd have to PInvoke into FindFirstFile et al. to do searches effectively.
Ok, I think I solved the case, I just iterated each folder, checked their attributes and then added to the list.. I think it's working.. Plz check it a bit..
Dim tempDir As New DirectoryInfo(path)
Dim FileDetails(4) As String
Dim iTem As ListViewItem
Try
Dim allFiles As FileInfo() = Nothing
For Each Directory In tempDir.GetDirectories()
Try
If (Directory.Attributes <> FileAttributes.System) Then
allFiles = Directory.GetFiles("*.pdf", SearchOption.AllDirectories)
End If
Dim oneFIle As FileInfo
For Each oneFIle In allFiles
FileDetails(0) = oneFIle.Name()
FileDetails(1) = oneFIle.FullName()
FileDetails(2) = oneFIle.Length() / (1024 * 1024)
FileDetails(2) = FileDetails(2).Remove(5)
iTem = New ListViewItem(FileDetails)
ListView1.Items.Add(iTem)
Next
Catch ex As Exception
End Try
Next
Catch ex As UnauthorizedAccessException
End Try
System Volume Information Folder is a O/S protected folder. Even though you may have administrative access, you still will not be able to access it. You can try it from Explorer itself. (Need to enable option to show protected Operating System files.)