'A generic error occurred in GDI+.' saving image to anywhere not Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) - vb.net

Hoping someone here can help me. I've read the many other similar questions on StackOverflow but haven't found an answer that works for me...
I have code that exports data into an excel report. Part of that code copies an image and places it into a folder just created on the desktop. Then also inserts that image into the excel report. There are two different ways data is exported. Users can export one item at a time, or an entire program of items. When exporting one Item a folder is created on the Desktop with the ItemID, and the image is saved in that folder. When exporting a program a folder is craeted on the desktop for the Program, another folder is created inside that folder for vendor, and anther inside the vendor forlder for the item; Then the image is saved in that item folder. The code works just fine When exporting only an item, but gives an error...
A generic error occurred in GDI+
...on the first image save when exporting a program.
The code to Call the method when exporting one Item is...
Rprt_ItemRFQ_Class.ExportRFQ(Itm_ItemIDCmb.Text, ItmKey, Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), ProgKey)
The Code to Export a group of Items is...
Dim SaveFold As String = IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), ProgName, VendName)
My.Computer.FileSystem.CreateDirectory(SaveFold)
For Each RFQRow As DataRow In DS.RFQRequestForm.Rows()
Rprt_ItemRFQ_Class.ExportRFQ(RFQRow.Item("ItemID"), RFQRow.Item("ItmKey"), SaveFold, ProgKey)
Next
The Code being called is... (SaveFold is a class variable)
Public Shared Sub ExportRFQ(ItemID As String, ItmKey As Integer, StartPath As String, ProgKey As Integer)
SaveFold = IO.Path.Combine(StartPath, ItemID)
My.Computer.FileSystem.CreateDirectory(SaveFold)
"I have cut out all the code for creating and formatting the excel sheet as it is not relevent"
ImgLoad(ItmKey, ItemID)
End Sub
Public Shared Sub ImgLoad(ItmKey As Integer, ItemID As String)
GetPrimImg.Fill(DS.GetPrimImage, ItmKey)
Dim FileStr As String = DS.GetPrimImage.Rows(0).Item(0)
Dim NewPath As String = IO.Path.Combine(SaveFold, ItemID & ".jpg")
Dim fs As IO.FileStream
fs = New IO.FileStream(FileStr, IO.FileMode.Open, IO.FileAccess.ReadWrite)
Dim RFQImg As System.Drawing.Image = System.Drawing.Image.FromStream(fs)
RFQImg.Save(NewPath)
Dim Wid As Integer = IIf(RFQImg.Width = 450, RFQImg.Width * 0.53333, RFQImg.Width * 0.24)
Dim Hgt As Integer = IIf(RFQImg.Height = 450, RFQImg.Height * 0.53333, RFQImg.Height * 0.24)
RFQImg.Dispose()
fs.Close()
xlWorksheet.Range("T1").Select()
Dim P As Object = xlWorksheet.Pictures.Insert(NewPath)
With P
.Left = xlWorksheet.Range("T1").Left
.Top = xlWorksheet.Range("T1").Top
.Placement = ExcelVB.XlPlacement.xlMoveAndSize
.PrintObject = True
With P.ShapeRange
.LockAspectRatio = False
.Width = Wid
.Height = Hgt
.IncrementTop(3.333228)
.IncrementLeft(102.1872441)
End With
End With
End Sub
The Error Occurs on the line
RFQImg.Save(NewPath)
I have tried modifying what gets passed in as SaveFold from the program export, it works just fine if I pass in Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), but any other file path I pass in causes the error.

Ok, I'm kind of an idiot here. Someone saved the vendor name which was the VendName variable with a space character at the end. That is why I was getting the error. I added a trim to the variables and all is good now.

Related

Iterate through a directory to get subfolders and certain files

I am working on a program that will move files to a database, text files to be exact. The user will have a starting directory and inside will multiple sub folders and files and so on. I want to go through each Folder and sub folder looking for the text files and add them accordingly to the database so it resembles a directory structure in a way. In the program the files are organized such as the folders are "Categories" that are displayed into a tree view.I am only adding the folder names(as Categories) that do contain text files and their subs and so forth. As well I need to figure out where to plug in the adding of the "Category". As of right now I am using a couple of listboxes for my output until I can get it all figured out.
lstfiles.Items.Add(Dir)
For Each file In System.IO.Directory.GetFiles(Dir)
Dim fi As System.IO.FileInfo = New IO.FileInfo(file)
If fi.Extension = ".txt" Then
If lstRootFolderFiles.Items.Contains(file) = False Then
lstfiles.Items.Add(file)
AddFile(file, Gennumber(9999))
End If
End If
Next
For Each folder In System.IO.Directory.GetDirectories(Dir)
lstfiles.Items.Add(folder)
For Each file In System.IO.Directory.GetFiles(folder)
Dim fi As System.IO.FileInfo = New IO.FileInfo(file)
If fi.Extension = ".txt" Then
If lstRootFolderFiles.Items.Contains(file) = False Then
lstfiles.Items.Add(file)
End If
End If
Next
Next
I have gotten so far as to iterate through the directory and get files but it returns folders that are empty. And I need to figure out where I need to put in my addcategory function. And also remember the last one that was added so they can be added as a subcategory.
I think I am making a big mess of it all, or over thinking the whole thing.
Any assistance or guidance would be appreciated.Thank you
The end result that I came up with was much different from my original posting, as it was my way of thinking of how it was going to work. I split up the two main functions. Retrieving the Folders and retrieving the files.
DirEx is the Import Directory, CatID is the Tag of the selected Treenode where the folders are going to added in.
Private Sub DirImport_GetSubDirectories(ByVal DirEx As String, ByVal CatID As Integer)
Try
Dim ClsData As New clsNoteData
'Set the DatabaseFile Property of the class
ClsData.Database = LoadedLibraryDatabase
' Get all subdirectories
Dim subdirectoryEntries() As String = Directory.GetDirectories(DirEx)
' Loop through them to see if they have any other subdirectories
Dim subdirectory As String
For Each subdirectory In subdirectoryEntries
'If the Directory is not Empty
If Not Directory.GetFileSystemEntries(subdirectory).Length = 0 Then
Dim di As DirectoryInfo = New DirectoryInfo(subdirectory)
'Creating Random Number
Dim NewCatID As Integer = GenNumber(9999)
'Call for a new Sub Category
ClsData.NewSubCategoryNode(LoadedLibraryDatabase, NewCatID, CatID, di.Name, -1)
'Get files in the current Directory
DirImport_GetFiles(subdirectory, NewCatID)
'Get the next set of Subfolders
DirImport_GetSubDirectories(subdirectory, NewCatID)
End If
Next
Catch ex As Exception
End Try
End Sub
Private Sub DirImport_GetFiles(ByVal DirEx As String, ByVal CatID As Integer)
Dim Files() As String = Directory.GetFiles(DirEx, "*.txt")
Dim file As String
For Each file In Files
Dim clsNoteData As New clsNoteData
Dim fi As FileInfo = New FileInfo(file)
clsNoteData.Database = LoadedLibraryDatabase
clsNoteData.NewNote_ID = GenNumber(99999)
clsNoteData.NewNote_CatID = CatID
clsNoteData.NewNote_Title = Path.GetFileNameWithoutExtension(file)
clsNoteData.NewNote(False, file)
Next
End sub
So here it is for anyone who may want to do something similar.

How to keep the content of ListBox in Vb.net

If i want to keep the content of a textbox i do this
TextBox1.Text = TextBox1.Text & Something
Is there a way to do the same thing for the content of Items of a Listbox?
In my RichTextBox3 i have the list of files in the C:\Work directory
I Tried this code but it's giving me The content of the last line (It's not adding the lines before)
Do Until number = RichTextBox3.Lines.Length
Dim directory = "C:\Work\" & RichTextBox3.Lines(number)
Dim files() As System.IO.FileInfo
Dim dirinfo As New System.IO.DirectoryInfo(directory)
files = dirinfo.GetFiles("*", IO.SearchOption.AllDirectories)
For Each file In files
ListBox1.Items.Add(file)
Next
number = number + 1
Loop
Help is appreciated
Thanks to all of you
I'm not sure that this will address your stated problem but there's a serious issue with that code and I need to provide a long code snippet to address it and that won't be readable in a comment.
The Lines property of a TextBox or RichTextBox is not "live" data, i.e. it doesn't refer to an array stored within the object. Each time you get the property, a new array is created. You are getting RichTextBox3.Lines twice for every iteration of that loop, so that's obviously wrong. You also should not be adding items to the ListBox one by one like that. You should be creating a list of all the items first, then adding them all with a single call to AddRange:
Dim files As New List(Of FileInfo)
For Each line In RichTextBox3.Lines
Dim folderPath = Path.Combine("C:\Work", line)
Dim folder As New DirectoryInfo(folderPath)
files.AddRange(folder.GetFiles("*", SearchOption.AllDirectories))
Next
ListBox1.Items.AddRange(files.ToArray())
If that code doesn't work as expected, you can debug it and view the contents of files at various stages to make sure that you are getting the files you expect. It might also be worth testing folder.Exists before calling GetFiles, unless you're absolutely sure that each line in the RichTextBox represents an existing folder.
This will do what you want.
number = 0
ListBox1.items.clear()
Do Until number = RichTextBox3.Lines.Length
Dim directory = "C:\Work\" & RichTextBox3.Lines(number)
Dim files() As System.IO.FileInfo
Dim dirinfo As New System.IO.DirectoryInfo(directory)
files = dirinfo.GetFiles("*", IO.SearchOption.AllDirectories)
For Each file In files
ListBox1.Items.Add(file)
Next
number = number + 1
Loop

Upload and replace the same image file if it already exist

I have a picturebox named PB_Company_Logo and I have a button named btn_Save and within this button I have this function which saves the image in PB_Company_Logo to current_directory/images
Public Sub save_PB(PB_Name As PictureBox)
Dim filename As String = "company_logo.png"
Dim path As String = Directory.GetCurrentDirectory() & "\images"
Dim filename_path As String = System.IO.Path.Combine(path, filename)
If (Not System.IO.Directory.Exists(path)) Then
System.IO.Directory.CreateDirectory(path)
PB_Name.Image.Save(filename_path)
Else
PB_Name.Image.Save(filename_path)
End If
End Sub
The problem is, there are cases where the user will upload a new company_logo.png. I want the system to treat the uploading of new image as replacing the former company_logo.png.
I think the error in this line of code means that the file is currently in used (locked) and therefore cannot be replaced.
Else
PB_Name.Image.Save(filename_path)
End If
When you load a pictureBox control with an image file the ide (vs) puts a lock on the file. This happens when you set the image property of the pictureBox control to a file at design time.
You can use the FileStream object.
Example:
Dim fs As System.IO.FileStream
' Specify a valid picture file path on your computer.
fs = New System.IO.FileStream("C:\WINNT\Web\Wallpaper\Fly Away.jpg",
IO.FileMode.Open, IO.FileAccess.Read)
PictureBox1.Image = System.Drawing.Image.FromStream(fs)
fs.Close()
After you have done the workaround you can then use the System.IO.File.Exists(img) namespace to check wether or not a picture exists.
Example: This checks if the image passed through already exists and if it does then it will replace it.
Dim imageStr As String = "~/images/name.jpg"
If System.IO.File.Exists(imageStr) Then
Image1.ImageUrl = "~/images/name.jpg"
End If

Update a table linked to a PowerPivot datamodel using EPPlus and it corrupts the datamodel

Using EPPlus I read an XLSX file.
I replace the data in a table and set the table range.
When I open the resulting spreadsheet I get an error:
"We found a problem with some content in 'MySpreadsheet.xlsx'. Do you want us to try to recover as much as we can?" -- I click Yes and I get another error:
"Excel was able to open the file by repairing or removing the unreadable content. Removed Part: Data store"
The error only happens after I add this table to a PowerPivot data model.
[EDIT] - I created a win forms app that reproduces this problem. You
can download it at here
I found the problem but don't know how
to fix it.
rename the xlsx to zip
Open the zip and browse to the xl\workbook.xml file
Look for the node collection.
Notice how EPPlus changes the <definedNames> collection to use absolute cell addresses.
Excel: <definedName name="_xlcn.LinkedTable_MyDate" hidden="1">MyDate[]</definedName>
EPPlus: <definedName name="_xlcn.LinkedTable_MyDate" hidden="1">'MyDate'!$A$2:$A$5</definedName>
If I modify this line after EPPlus is done saving then I can pull it
up in Excel without corrupting the Data Model.
I tried changing the WorkbookXml but it is happening when the
ExcelPackage.Save method runs.
For Each node In pck.Workbook.WorkbookXml.GetElementsByTagName("definedNames")(0).ChildNodes
node.innerText = "MyDate[]"
Next
Any ideas?
Try this first: create a spreadsheet with one table in it. Name the worksheet and table "DateList". Save it and run the below code on it -- it will work.
Then do this: open the same spreadsheet and add the DateList table to a pivottable data model. Save it and run the below code on it -- it will fail.
Here's some code from my MVC Controller -- only the relevant bits:
Public Class ScorecardProgressReportDatesVM
Public Property WeekRange As Date
End Class
Public Function GetScorecardProgressReport(id As Integer) As ActionResult
Dim contentType As String = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Dim DateList As New List(Of ScorecardProgressReportDatesVM)
DateList.Add(New ScorecardProgressReportDatesVM With {.WeekRange = CDate("Jan 1, 2015")})
DateList.Add(New ScorecardProgressReportDatesVM With {.WeekRange = CDate("Jan 1, 2015")})
Dim templateFile As New IO.FileInfo("c:\test.xlsx")
Dim ms As New IO.MemoryStream
Using pck As New ExcelPackage(templateFile)
ExtendTable(pck, "DateList", DateList)
pck.SaveAs(ms)
ms.Position = 0
End Using
Dim fsr = New FileStreamResult(ms, contentType)
fsr.FileDownloadName = "StipProgress.xlsx"
Return fsr
End Function
Private Sub ExtendTable(package As ExcelPackage, tableName As String, newList As Object)
Dim ws As OfficeOpenXml.ExcelWorksheet
ws = package.Workbook.Worksheets(tableName)
Dim OutRange = ws.Cells("A1").LoadFromCollection(newList, True)
Dim t = ws.Tables(tableName)
Dim te = t.TableXml.DocumentElement
Dim newRange = String.Format("{0}:{1}", t.Address.Start.Address, OutRange.End.Address)
te.Attributes("ref").Value = newRange
te("autoFilter").Attributes("ref").Value = newRange
End Sub
In order to fix this we had to change the EPPlus v4.04 source code.
ExcelWorkbook.cs # line 975 was changed
//elem.InnerText = name.FullAddressAbsolute; This was causing issues with power pivot
to
elem.InnerText = name.FullAddress; //Changed to full address... so far everything is working

VB trouble loading data from a text file to list box

I am trying to get my application to show data from a text file to a list box with visual basics. I have it working for small sized text files no problem, but it will not work for text files the size of say 20mb. Is there any reason why it wouldn't load such or maybe some kind of limitations?
I forgot to ask, could it possibly just a matter of having to wait a long time? The program just sits there and I can't interact with it while it's getting the data...I think anyway....
Sub OpenFiles()
Dim myName As String = Dir(downloadTo + "*.TXT")
Do While myName <> ""
lstFiles.Items.Add(myName)
myName = Dir()
Loop
End Sub
Sub ReadFiles(textFile As String)
Dim logReader As New System.IO.StreamReader(textFile)
lstSrchTxt.Items.Clear()
While logReader.EndOfStream <> True
Dim stringx As String = logReader.ReadLine
If stringx.Contains(searchText) Then
lstSrchTxt.Items.Add(stringx)
End If
End While
logReader.Close()
End Sub
The issue was that I was entering too much data and it needed time to process all of the characters.