Do...Loop starts too quickly, how to brake it? - vb.net

With my program, user have to download and save csv files to two different specific directories. Unfortunately automatic downloading not possible. To download file I use command WebBrowser1.Navigate(url), which run php script on the target web page and after one second webBrowser ask path where I or user want to download file. After that again button click and .Navigate to download second one.
But I have to be sure, that user had download file exactly to the specific directory and first, I want to check if file exists there. And here problems are starts. Because of small delay before "Save" possibility, program run immediately Do...Loop process and "Save" window doesn't even come. Also I tried to use thread.sleep, but it doesn't help. Because it immediately go to sleep and "save" window have not time to present. After sleep it immediately starts Do...Loop process.
Is here some other instruments to say to my program, that it wait a little and continue to run code after user "Save" file?
Here is My code:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim kraporttila As String
Dim dt1 As Date = DateTimePicker1.Value
Dim dt2 As Date = DateTimePicker2.Value
Dim faa As String = dt1.ToString("yyyy-MM-dd")
Dim fla As String = dt2.ToString("yyyy-MM-dd")
Dim ddla As String = dt2.ToString("MM.yy")
Dim kuitti As Uri = New Uri("https:url/kuitti.php?faa=" & faa & "&fla=" & fla & "&fk_e=&fa_e=&fm=&ftil=&kuittiexportcsv=Lataa%CSV")
WebBrowser1.Navigate(kuitti)
Button2.Visible = False
Do While
If System.IO.File.Exists(kraporttila) = True Then
Button3.Text = "Lataa maksuvirheet"
Button3.Visible = True
Label3.Text = "Nyt lataa maksuviheet ja tellenna kansioon ""C:\Users\Ivan\" & ddla & "\Laskutukset ja Maksuvirheet\Maksuvirheet"""
Exit Do
Else
Continue Do
End If
Loop
End Sub

Related

Moving Files From One Folder To Another VB.Net

I am trying to figure out how to move 5 files
settings.txt
settings2.txt
settings3.txt
settings4.txt
settings5.txt
from one folder to another.
Although I know what the file names will be and what folder Name they will be in, I don't know where that folder will be on the Users computer.
My thought process is to use a FolderBrowseDialog which the user can browse to where the Folder is, and then when OK is pressed, it will perform the File copy to the destination folder, overwriting what's there.
This is what I have so far.
Dim FolderPath As String
Dim result As Windows.Forms.DialogResult = FolderBrowserImport.ShowDialog()
If result = DialogResult.OK Then
FolderPath = FolderBrowserImport.SelectedPath & "\"
My.Computer.FileSystem.CopyFile(
FolderPath & "settings.txt", "c:\test\settings.txt", overwrite:=True)
ElseIf result = DialogResult.Cancel Then
Exit Sub
End If
Rather than run this 5 times, is there a way where it can copy all 5 files at once
I know why IdleMind recommended the approach they did, but it would probably make for a bit more readable code to just list out the file names:
Imports System.IO
...
Dim result = FolderBrowserImport.ShowDialog()
If result <> DialogResult.OK Then Exit Sub
For Each s as String in {"settings.txt", "settings2.txt", "settings3.txt", "settings4.txt", "settings5.txt" }
File.Copy( _
Path.Combine(FolderBrowserImport.SelectedPath, s), _
Path.Combine("c:\test", s), _
True _
)
Next s
You can swap this fixed array out for a list that VB prepares for you:
For Each s as String in Directory.GetFiles(FolderBrowserImport.SelectedPath, "settings*.txt", SearchOption.TopDirectoryOnly)
File.Copy(s, Path.Combine("c:\test", Path.GetFilename(s)), True)
Next s
Tips:
It's usually cleaner to do a If bad Then Exit Sub than a If good Then (big load of indented code) End If - test all your known failure conditions at the start and exit the sub if anything fails, rather than arranging a huge amount of indented code
Use Path.Combine to combine path and filenames etc; it knows how to deal with stray \ characters
Use Imports to import namespaces rather than spelling everything out all the time (System.Windows.Forms.DialogResult - a winforms app will probably have all the necessaries imported already in the partial class so you can just say DialogResult. If you get a red wiggly line, point to the adjacent lightbulb and choose to import System.WIndows/Forms etc)
Once you have the selected folder, use a For loop to build up the names of the files you're looking for. Use System.IO.File.Exists() to see if they are there. Use System.IO.Path.Combine() to properly combine your folders with the filenames.
Here's a full example (without exception handling, which should be added):
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If FolderBrowserImport.ShowDialog() = DialogResult.OK Then
Dim FolderPath As String = FolderBrowserImport.SelectedPath
For i As Integer = 1 To 5
Dim FileName As String = "settings" & If(i = 1, "", i) & ".txt"
Dim FullPathFileName As String = System.IO.Path.Combine(FolderPath, FileName)
If System.IO.File.Exists(FullPathFileName) Then
Dim DestinationFullPathFileName = System.IO.Path.Combine("c:\test", FileName)
My.Computer.FileSystem.CopyFile(FullPathFileName, DestinationFullPathFileName, True)
Else
' possibly do something in here if the file does not exist?
MessageBox.Show("File not found: " & FullPathFileName)
End If
Next
End If
End Sub

Check if Mage.exe batch manifest update was successful or not - ClickOnce

I have created a console app that creates a batch file in code, that will automatically update and re-sign my app manifest file using mage.exe when a new version gets published.
This batch file then gets executed by the same console app after it has created it.
I want to know if there is a way to determine if the mage.exe batch file failed in updating or signing the manifest?
Any help or ideas will be appreciated.
UPDATE
As per TnTinMn's comment, I forced the batch to fail on updating the manifest. This returned a exit code of 1. How is it then possible for me to extract that exit code to do my error handling? Im doing the following:
Dim procInfo As New ProcessStartInfo()
procInfo.UseShellExecute = True
procInfo.FileName = (sDriveLetter & ":\updatemanifest.bat")
procInfo.WorkingDirectory = ""
procInfo.Verb = "runas"
procInfo.WindowStyle = ProcessWindowStyle.Hidden
Dim sval As Object = Process.Start(procInfo) 'I tested the object to see if there is indeed a value that i can use.
While debugging and looking at the sval object's properties, the exit code is set to 1 but i can't seem to extract it from there.
There are two ways (that I know of) that you can wait for the process to exit before retrieving the Process.ExitCode.
The first as is a blocking call: Process.WaitForExit
and the second is to use the Exit event.
Private Sub RunProcess()
Dim psi As New ProcessStartInfo()
psi.UseShellExecute = True
psi.WindowStyle = ProcessWindowStyle.Hidden
psi.FileName = "cmd.exe"
psi.Arguments = "/c Exit 100"
Dim proc As Process = Process.Start(psi)
proc.EnableRaisingEvents = True
AddHandler proc.Exited, AddressOf ProcessExited
End Sub
Private Sub ProcessExited(sender As Object, e As EventArgs)
Dim proc As Process = DirectCast(sender, Process)
proc.Refresh()
Dim code As Int32 = proc.ExitCode
Me.BeginInvoke(Sub() MessageBox.Show(String.Format("Process has exited with code: {0}", code)), Nothing)
proc.Dispose()
End Sub

Can't Multi Download With WebClient

I know this question has been asked before, but I have a special way I want to download the files through a webclient, I want to download each file at a time through a Do While statement, but it just adds the file to download and moves on to the next task that also downloads another file so it cancels each other out and crashes the application.
Private Function StartDownloads()
Dim wc As New WebClient
AddHandler wc.DownloadProgressChanged, AddressOf DownloadProgressChanged
AddHandler wc.DownloadFileCompleted, AddressOf DownloadFileCompleted
Dim delimiterChars As Char() = {"+"c}
Dim words As String() = RichTextBox1.Text.Split(delimiterChars)
Dim i As Integer = 1
Do While (i < words.Length)
Dim delimiterChars1 As Char() = {"|"c}
Dim words1 As String() = words(i).Split(delimiterChars1)
Dim name As String = words1(0)
Dim fileurl As String = words1(2)
ToolStripStatusLabel1.Text = "Downloading " & name & ":"
wc.DownloadFileAsync(New System.Uri(fileurl), Path.GetTempPath() & "\" & name)
i = (i + 1)
Loop
End Function
AND
Private Sub DownloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs)
ProgressBar1.Value = e.ProgressPercentage
ToolStripStatusLabel2.Text = String.Format("{0} MB's / {1} MB's",
(e.BytesReceived / 1024D / 1024D).ToString("0.00"),
(e.TotalBytesToReceive / 1024D / 1024D).ToString("0.00"))
End Sub
So basically in the Do While statement it starts the download then continues without waiting for the download to finish and then downloads both at once, which then crashes the program/interferes with the labels displaying the download name, the reason this is a different question from others is I need it to specify the download name as I can't do with other tutorials, by adding the downloads to a list...
So if anyone can help me make the Do While statement wait for the download to finish then continue with the next without loosing the file name and stuff like that, please give me some tips, thanks!
I know that DownloadFile waits for the download to finish then continues, but I need it to show download progress and download bytes and stuff like that...
P.S. Sorry if this is confusing as it's hard to explain, thanks.
By adding await wc.DownloadFileTaskAsync(...), it worked perfectly

Open, Launch or Show a file for the user to read or write in vb.net

It sounds very simple but I have searched and cannot seem to find a way to open a log file which the user just created from my windows form app. The file exits I just want to open it after it is created.
I have a Dim path As String = TextBox1.Text and once the user names and clicks ok on the savefiledialog I have a msgbox that says "Done" and when you hit OK I have tried this
FileOpen(FreeFile, path, OpenMode.Input) but nothing happens. I just want it to open the log and show it to the user so they can edit or save it again or anything.
This is where I got the above code.
http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.filesystem.fileopen.aspx
Searching is difficult because everyone is trying to "Open" a file and process it during runtime. I am just trying to Show a file by Launching it like someone just double clicked it.
Here is the entire Export Button click Sub. It basically writes listbox items to file.
Private Sub btnExport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExport.Click
Dim sfd As New SaveFileDialog
Dim path As String = TextBox1.Text
Dim arypath() As String = Split(TextBox1.Text, "\")
Dim pathDate As String
Dim foldername As String
foldername = arypath(arypath.Length - 1)
pathDate = Now.ToString("yyyy-MM-dd") & "_" & Now.ToString("hh;mm")
sfd.FileName = "FileScannerResults " & Chr(39) & foldername & Chr(39) & " " & pathDate
sfd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal)
sfd.Filter = "Text files (*.txt)|*.txt|CSV Files (*.csv)|*.csv"
sfd.ShowDialog()
path = sfd.FileName
Using SW As New IO.StreamWriter(path)
If CkbxFolder.Checked = True Then
SW.WriteLine("Folders")
For Each itm As String In ListBox1.Items
SW.WriteLine(itm)
Next
End If
If CkbxFiles.Checked = True Then
SW.WriteLine("Files")
For Each itm As String In ListBox2.Items
SW.WriteLine(itm)
Next
End If
End Using
MsgBox("Done...")
FileOpen(FreeFile, path, OpenMode.Input) 'Why can't I open a file for you...
End Sub
Do not use the old VB6 methods. They are still here for compatibility reason, the new code should use the more powerful methods in the System.IO namespace.
However, as said in comments, FileOpen don't show anything for you, just opens the file
You coud write
Using sr = new StreamReader(path)
Dim line = sr.ReadLine()
if !string.IsNullOrEmpty(line) Then
textBoxForLog.AppendText(line)
End If
End Using
or simply (if the file is not too big)
Dim myLogText = File.ReadAllText(path)
textBoxForLog.Text = myLogText
As alternative, you could ask the operating system to run the program associated with the file extension and show the file for you
Process.Start(path)
To get the same behavior as if the user double-clicked it, just use System.Diagnostics.Process, and pass the filename to it's Start method:
Process.Start(path)
This will open the file using whatever the default application is for that filename based on its extension, just like Explorer does when you double-click it.

VB.Net: How To Display Previous Shadow Copy Versions of File Allowing User to Choose One

I'm writing an Excel file recovery program with VB.Net that tries to be a convenient place to gather and access Microsoft's recommended methods. If your interested in my probably kludgy, error filled, and lacking enough cleanup code it's here: http://pastebin.com/v4GgDteY. The basic functionality seems to work although I haven't tested graph macro table recovery yet.
It occurred to me that Vista and Windows 7 users could benefit from being offered a list of previous versions of the file within my application if the Shadow Copy Service is on and there are previous copies. How do I do this?
I looked at a lot of web pages but found no easy to crib code. One possibility I guess would be to use vssadmin via the shell but that is pretty cumbersome. I just want to display a dialogue box like the Previous Versions property sheet and allow users to pick one of the previous versions. I guess I could just display the previous version property sheet via the shell by programmatically invoking the context menu and the "Restore previous versions choice", however I also want to be able to offer the list for Vista Home Basic and Premium Users who don't have access to that tab even though apparently the previous versions still exist. Additionally if it possible I would like to offer XP users the same functionality although I'm pretty sure with XP only the System files are in the shadow copies.
I looked at MSDN on the Shadow Copy Service and went through all the pages, I also looked at AlphaVSS and AlphaFS and all the comments. I'm kind of guessing that I need to use AlphaVss and AlphFS and do the following?
Find out the list of snapshots/restore points that exist on the computer.
Mount those snapshots.
Navigate in the mounted volumes to the Excel file the user wants to recover and make a list of those paths.
With the list of paths handy, compare with some kind of diff program, the shadow copies of the files with the original.
Pull out the youngest or oldest version (I don't think it matters) of those shadow copies that differ from the recovery target.
List those versions of the files that are found to be different.
This seems cumbersome and slow, but maybe is the fastest way to do things. I just need some confirmation that is the way to go now.
I finally decided to go ahead and start coding. Please make suggestions for speeding up the code or what do with files that are found to be different from the recovery file target. Is there a simpler way to do this with AlphaVSS and AlphaFS?
Private Sub Button1_Click_2(sender As System.Object, e As System.EventArgs) Handles Button1.Click
'Find out the number of vss shadow snapshots (restore
'points). All shadows apparently have a linkable path
'\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy#,
'where # is a simple one, two or three digit integer.
Dim objProcess As New Process()
objProcess.StartInfo.UseShellExecute = False
objProcess.StartInfo.RedirectStandardOutput = True
objProcess.StartInfo.CreateNoWindow = True
objProcess.StartInfo.RedirectStandardError = True
objProcess.StartInfo.FileName() = "vssadmin"
objProcess.StartInfo.Arguments() = "List Shadows"
objProcess.Start()
Dim burp As String = objProcess.StandardOutput.ReadToEnd
Dim strError As String = objProcess.StandardError.ReadToEnd()
objProcess.WaitForExit()
Dim xnum As Integer = 0
Dim counterVariable As Integer = 1
' Call Regex.Matches method.
Dim matches As MatchCollection = Regex.Matches(burp, _
"HarddiskVolumeShadowCopy")
' Loop over matches.
For Each m As Match In matches
xnum = xnum + 1
'At the max xnum + 1 is the number of shadows that exist
Next
objProcess.Close()
Do
'Here we make symbolic links to all the shadows, one at a time
'and loop through until all shadows are exposed as folders in C:\.
Dim myProcess As New Process()
myProcess.StartInfo.FileName = "cmd.exe"
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.RedirectStandardInput = True
myProcess.StartInfo.RedirectStandardOutput = True
myProcess.StartInfo.CreateNoWindow = True
myProcess.Start()
Dim myStreamWriter As StreamWriter = myProcess.StandardInput
myStreamWriter.WriteLine("mklink /d C:\shadow" & counterVariable _
& " \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy" _
& counterVariable & "\")
myStreamWriter.Close()
myProcess.WaitForExit()
myProcess.Close()
' Here I compare our recovery target file against the shadow copies
Dim sFile As String = PathTb.Text
Dim sFileShadowPath As String = "C:\shadow" & _
counterVariable & DelFromLeft("C:", sFile)
Dim jingle As New Process()
jingle.StartInfo.FileName = "cmd.exe"
jingle.StartInfo.UseShellExecute = False
jingle.StartInfo.RedirectStandardInput = True
jingle.StartInfo.RedirectStandardOutput = True
jingle.StartInfo.CreateNoWindow = True
jingle.Start()
Dim jingleWriter As StreamWriter = jingle.StandardInput
jingleWriter.WriteLine("fc """ & sFile & """ """ _
& sFileShadowPath & """")
jingleWriter.Close()
jingle.WaitForExit()
Dim jingleReader As StreamReader = jingle.StandardOutput
Dim JingleCompOut As String = jingleReader.ReadToEnd
jingleReader.Close()
jingle.WaitForExit()
jingle.Close()
Dim jingleBoolean As Boolean = JingleCompOut.Contains( _
"no differences encountered").ToString
If jingleBoolean = "True" Then
MsgBox(jingleBoolean)
Else
'I haven't decided what to do with the paths of
'files that are different from the recovery target.
MsgBox("No")
End If
counterVariable = counterVariable + 1
Loop Until counterVariable = xnum + 1
End Sub