OpenFileDialog under the hood - vb.net

This is my first question here because I ended up in dead end.
I'm using ZIP 2 Secure EXE (very good software from Chilkat) to create setup.exe for application. ZIP 2 Secure EXE can be run without GUI with one or more parameters.
The problem is that when I call ZIP 2 Secure EXE (ChilkatZipSE.exe) without using OpenFileDialog form to determine location of ChilkatZipSE.exe, it doesn't run process with System.Diagnostics.Process class. The way I call ChilkatZipSE.exe is "..\ChilkatZipSE.exe -cfg settings.xml". Everything is OK with settings.xml and there is UnlockCode node which is needed for creating setup.exe file. When I use OpenFileDialog ChilkatZipSE.exe creates desired setup.exe and it's working fine.
Bellow is my code that I use:
Private Sub btnStartApp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStartApp.Click
If txtExtAppPath.Text.Length > 0 AndAlso System.IO.File.Exists(txtExtAppPath.Text) Then
Dim myFile As New FileInfo(txtExtAppPath.Text)
txtExtAppLog.Text = StartApplication(myFile.FullName, txtExtParams.Text, chkIsHidden.Checked)
'txtExtAppLog.Text = StartApplication(txtExtAppPath.Text, txtExtParams.Text, chkIsHidden.Checked)
End If
End Sub
Public Function StartApplication(ByVal fileFullPath_ As String, ByVal fileParameter_ As String, ByVal isHidden_ As Boolean) As String
Dim lassie As String = String.Empty
Try
Dim newProcess As New ProcessStartInfo()
newProcess.FileName = fileFullPath_
newProcess.Arguments = fileParameter_
If isHidden_ Then newProcess.WindowStyle = ProcessWindowStyle.Hidden
If System.IO.File.Exists(fileFullPath_) Then
Using startedNewProcess As Process = Process.Start(newProcess)
'startedNewProcess.EnableRaisingEvents = True
startedNewProcess.WaitForExit()
End Using
Else
lassie = "File " + fileFullPath_ + " doesn't exist."
End If
Catch ex As Exception
lassie = ex.Message
End Try
Return lassie
End Function
Thanks, magnumx.

the problem was the given parameter. When using OpenFileDialog it knows where settings.xml is. But when calling "..\ChilkatZipSE.exe -cfg settings.xml" without OpenFileDialog it must be used as "..\ChilkatZipSE.exe -cfg ..\settings.xml"

Related

Move file in Windows-Service

This is my first time making a windows service app. I'm trying to move files from one folder to another using a windows service app. It'll do so every 10 seconds.
This is the code I'm using. It works when I use it on a windows form app but doesn't work when I use it on a windows-service app.
The code in the Timer1_Tick works if I use it in OnStart. But doesn't work in the timer.
Protected Overrides Sub OnStart(ByVal args() As String)
Timer1.Enabled = True
End Sub
Protected Overrides Sub OnStop()
Timer1.Enabled = False
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim FileToMove As String
Dim MoveLocation As String
Dim count1 As Integer = 0
Dim files() As String = Directory.GetFiles("C:\Documents and Settings\dmmc.operation\Desktop\Q8")
Dim pdfFiles(100) As String
For i = 0 To files.Length - 1
If Path.GetExtension(files(i)) = ".pdf" Then
pdfFiles(count1) = files(i)
count1 += 1
End If
Next
For i = 0 To pdfFiles.Length - 1
If pdfFiles(i) <> "" Then
FileToMove = pdfFiles(i)
MoveLocation = "C:\Documents and Settings\dmmc.operation\Desktop\Output\" + Path.GetFileName(pdfFiles(i))
If File.Exists(FileToMove) = True Then
File.Move(FileToMove, MoveLocation)
End If
End If
Next
End Sub
Windows.Forms.Timer won't work without a Form instantiated. You should be using System.Timers.Timer instead:
Private WithEvents m_timer As System.Timers.Timer
Protected Overrides Sub OnStart(ByVal args() As String)
m_timer = New System.Timers.Timer(1000) ' 1 second
m_timer.Enabled = True
End Sub
Private Sub m_timer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles m_timer.Elapsed
m_timer.Enabled = False
'Do your stuff here
m_timer.Enabled = True
End Sub
I've also build a service that moves files that are dropped into a folder but I'm using the FileSystemWatcher. The FileSystemWatcher allows me to move the file when a new one is created, create an entry in a SQL Database and send an email notification when it's all done.
This is how I have setup the FileSystemWatcher
Set a folder to watch: watcher.Path = "C:\Folder to Watch"
Set the file type to watch: watcher.Filter = "*.pdf".
The type of event to watch and the Method that gets triggered: watcher.Created += new FileSystemEventHandler(OnChanged);
Lastly, I need to enable the event: watcher.EnableRaisingEvents = true;
Unfortunately, I have instances on a daily basis where the files do not get moved successfully. I get IO exceptions for file in use. The files get copied but the file in the destination folder is 0kb.
I'm trying to troubleshoot it and I've manage to debug remotely but I still haven't figured out what I am doing wrong.
The most common error I get is: Error: System.IO.IOException: The process cannot access the file 'fileName.pdf' because it is being used by another process.
this error does not make sense as the file did not exist prior to my service trying to move it...
Any further help would be appreciated.

How to hide Windows 7 Open File Security when running certain EXE file using VB.NET?

Hello dearest community,
I am trying to build a simple AutoUpdate application using VB.NET. It was quite simple. That is, I put the newest ZIP file in my hosting site, and then download it using WebClient.DownloadFileAsync. After it get downloaded, I extract it using http://stahlforce.com/dev/unzip.exe
But each time I run the unzip.exe using Process.start, Windows 7 always show Open File Security.
Is it possible for VB.NET to bypass such security restriction?
Thanks.
Btw, this is my code of using WebClient.DownloadFileAsync, in case any one google about it and landed on this page :
Public Class AutoUpdate
Dim installationFolder As String = "C:\Program Files\xyz\abc\"
Dim updateFileNameTarget As String
Private Sub btnStartUpdte_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStartUpdte.Click
lblPercent.Text = ""
lblDownloading.Text = ""
lblDownloading.Text = ""
pbDownloadStatus.Value = 0
Dim wc As New WebClient
AddHandler wc.DownloadFileCompleted, AddressOf downloadComplete
AddHandler wc.DownloadProgressChanged, AddressOf progressChanged
Dim path As String = "http://xyz.abc.com/test.zip"
updateFileNameTarget = installationFolder & "test.zip"
Try
If File.Exists(updateFileNameTarget) Then
File.Delete(updateFileNameTarget)
End If
lblDownloading.Text = "Downloading " & path
wc.DownloadFileAsync(New Uri(path), updateFileNameTarget)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub progressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs)
pbDownloadStatus.Value = e.ProgressPercentage
lblPercent.Text = e.ProgressPercentage & "%"
End Sub
Private Sub downloadComplete(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)
MessageBox.Show("Download complete. Now extracting")
Dim cmd As String = Application.StartupPath & "\Tools\unzip.exe"
Dim arg As String = "-o """ & updateFileNameTarget & """"
Process.Start(cmd, arg)
End Sub
End Class
If you're already process-invoking everything else (including unzip), also use Sysinternal's streams.exe. Use the -d flag to remove the NTFS alternate data streams (ADS). There should only be one - and it is the one that indicates to Windows that the file was downloaded from an "untrusted source".
Your downloaded files will currently have a stream that looks like this:
:Zone.Identifier:$DATA 26
Remove this stream from the download files after extracting but before execution, and the warning will no longer appear.
See also: What is Zone Identifier? - and Accessing alternate data streams in files for a library to work with these within .NET without needing streams.exe.

Writing commands to cmd with Visual Basic

I'm using VirtualBox to attach a usb device. This usb device only works under 32 bit. My host os is Windows 7 64 bit, my Guest Windows 7 32 bit.
I found code to write to the command prompt and read it back out, this has been tested and works very well. But now after I have read and want to write again the command prompt just freezes. I have no idea why it does that... I also tried the command without VB and the driver attach fine.
Any ideas how I can solve this problem?
Public Class Form1
Private Results As String
Private test As Double
Private test2 As String
'The "Delegate" is used to correct the threading issue (Can't update control directly in VB.net 08/10), and invokes the needed text
update.
Private Delegate Sub delUpdate()
Private Finished As New delUpdate(AddressOf UpdateText)
Private Sub UpdateText()
resultsTextBox.Text = Results
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim CMDThread As New Threading.Thread(AddressOf CMDAutomate)
CMDThread.Start()
End Sub
Private Sub CMDAutomate()
Dim myprocess As New Process
Dim StartInfo As New System.Diagnostics.ProcessStartInfo
'Starts the CMD Prompt
StartInfo.FileName = "cmd.exe"
StartInfo.RedirectStandardInput = True
StartInfo.RedirectStandardOutput = True
'Required to redirect
StartInfo.UseShellExecute = False
'Disables the creation of a CMD Prompt outside application.
StartInfo.CreateNoWindow = False
myprocess.StartInfo = StartInfo
myprocess.Start()
Dim SR As System.IO.StreamReader = myprocess.StandardOutput
Dim SW As System.IO.StreamWriter = myprocess.StandardInput
'Runs the command you entered...
'SW.WriteLine(TextBox1.Text)
SW.WriteLine("cd C:\Program Files\Oracle\VirtualBox")
SW.WriteLine("vboxmanage list usbhost")
'Exits CMD Prompt
'SW.WriteLine("exit")
'Displayes the results...
Results = SR.ReadToEnd
'Im reading the string out to get the right Device id
test = InStr(Results, "0x0547", CompareMethod.Text)
test = test - 58
test2 = Mid(Results, test, 36)
'test2 gives 80be0bc1-6f69-4886-868f-c8857bff34c1
'this is the right id, if i try to input it myselves with:
'C:\Program Files\Oracle\VirtualBox>vboxmanage controlvm "test" usbattach
'80be0bc1-6f69-4886-868f-c8857bff34c1
'it works...
SW.WriteLine("vboxmanage controlvm " + Chr(34) + "test" + Chr(34) + "usbattach " + test2)
SW.WriteLine("exit")
Results = SR.ReadToEnd
SW.Close()
SR.Close()
'Invokes Finished delegate, which updates textbox with the results text
Invoke(Finished)
End Sub
End Class
I think ReadToEnd doesn't finish because the Command Window is still open. I would run half of your commands and then read it in after the EXIT command is called. Then you would simply need to parse the result string and run another Command Window process.

Simple software testing tool - VB.NET

ok, please do no laugh at this :x
i'm trying to create a simple software testing tool in VB.NET
i created a simple C program PROG.EXE which scans a number and prints the OUTPUT, and started building my tester, it should execute PROG.EXE output.txt, so PROG.EXE takes input from input.txt and prints the output to output.txt
but i failed, at first i tried Process.start then shell but nothing worked !
so i did this trick, the VB.NET codes generate a batch file with this codes PROG.EXE output.txt, but again i failed, though the VB.NET created the batch file and executes too, but nothing happened ! but when i manually run the batch file i got success !
i tried executing the batchfile then sendkey the VBCR/LF/CRLF still nothing happens !
whats wrong ?
My VB.NET Code, i am using Visual Studio 2010 Professional
Option Explicit On
Option Strict On
Public Class Form1
Dim strFileName As String
Private Sub btnRun_Click() Handles btnRun.Click
Dim strOutput As String
Using P As New Process()
P.StartInfo.FileName = strFileName
P.StartInfo.Arguments = txtInput.Text
P.StartInfo.RedirectStandardOutput = True
P.StartInfo.UseShellExecute = False
P.StartInfo.WindowStyle = ProcessWindowStyle.Hidden ' will this hide the console ?
P.Start()
Using SR = P.StandardOutput
strOutput = SR.ReadToEnd()
End Using
End Using
txtOutput.Text = strOutput
End Sub
Private Sub btnTarget_Click() Handles btnTarget.Click
dlgFile.ShowDialog()
strFileName = dlgFile.FileName
lblFileName.Text = strFileName
End Sub
End Class
And this is my C code
#include<stdio.h>
#include<conio.h>
void main()
{
int x;
scanf("%d",&x);
printf("%d",(x*x));
}
my program runs perfectly when i run prog.exe <input.txt> output.txt in console
Below is a fully working example. You want to use the Process class as you tried but you need to RedirectStandardOutput on the process's StartInfo. Then you can just read the process's StandardOutput. The sample below is written using VB 2010 but works pretty much the same for older versions.
Option Explicit On
Option Strict On
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
''//This will hold the entire output of the command that we are running
Dim T As String
''//Create our process object
Using P As New Process()
''//Pass it the EXE that we want to execute
''//NOTE: you might have to use an absolute path here
P.StartInfo.FileName = "ping.exe"
''//Pass it any arguments needed
''//NOTE: if you pass a file name as an argument you might have to use an absolute path
P.StartInfo.Arguments = "127.0.0.1"
''//Tell the process that we want to handle the commands output stream
''//NOTE: Some programs also write to StandardError so you might want to watch that, too
P.StartInfo.RedirectStandardOutput = True
''//This is needed for the previous line to work
P.StartInfo.UseShellExecute = False
''//Start the process
P.Start()
''//Wrap a StreamReader around the standard output
Using SR = P.StandardOutput
''//Read everything from the stream
T = SR.ReadToEnd()
End Using
End Using
''//At this point T will hold whatever the process with the given arguments kicked out
''//Here we are just dumping it to the screen
MessageBox.Show(T)
End Sub
End Class
EDIT
Here is an updated version that reads from both StandardOutput and StandardError. This time it reads asynchronously. The code calls the CHOICE exe and passes an invalid command line switch which will trigger writing to StandardError instead of StandardOutput. For your program you should probably monitor both. Also, if you're passing a file into the program make sure that you are specifying the absolute path to the file and make sure that if you have spaces in the file path that you are wrapping the path in quotes.
Option Explicit On
Option Strict On
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
''//This will hold the entire output of the command that we are running
Dim T As String
''//Create our process object
Using P As New Process()
''//Pass it the EXE that we want to execute
''//NOTE: you might have to use an absolute path here
P.StartInfo.FileName = "choice"
''//Pass it any arguments needed
''//NOTE: if you pass a file name as an argument you might have to use an absolute path
''//NOTE: I am passing an invalid parameter to show off standard error
P.StartInfo.Arguments = "/G"
''//Tell the process that we want to handle the command output AND error streams
P.StartInfo.RedirectStandardOutput = True
P.StartInfo.RedirectStandardError = True
''//This is needed for the previous line to work
P.StartInfo.UseShellExecute = False
''//Add handlers for both of the data received events
AddHandler P.ErrorDataReceived, AddressOf ErrorDataReceived
AddHandler P.OutputDataReceived, AddressOf OutputDataReceived
''//Start the process
P.Start()
''//Start reading from both error and output
P.BeginErrorReadLine()
P.BeginOutputReadLine()
''//Signal that we want to pause until the program is done running
P.WaitForExit()
Me.Close()
End Using
End Sub
Private Sub ErrorDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
Trace.WriteLine(String.Format("From Error : {0}", e.Data))
End Sub
Private Sub OutputDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
Trace.WriteLine(String.Format("From Output : {0}", e.Data))
End Sub
End Class
Its important that you put your entire file path in quotes if it has spaces in it (in fact, you should always enclose it in quotes just in case.) For instance, this won't work:
P.StartInfo.FileName = "attrib"
P.StartInfo.Arguments = "C:\Program Files\Windows NT\Accessories\wordpad.exe"
But this will:
P.StartInfo.FileName = "attrib"
P.StartInfo.Arguments = """C:\Program Files\Windows NT\Accessories\wordpad.exe"""
EDIT 2
Okay, I'm an idiot. I thought you were just wrapping a filename in angled brackets like <input.txt> or [input.txt], I didn't realize that you were using actual stream redirectors! (A space before and after input.txt would have helped.) Sorry for the confusion.
There are two ways to handle stream redirection with the Process object. The first is to manually read input.txt and write it to StandardInput and then read StandardOutput and write that to output.txt but you don't want to do that. The second way is to use the Windows command interpreter, cmd.exe which has a special argument /C. When passed it executes any string after it for you. All stream redirections work as if you typed them at the command line. Its important that whatever command you pass gets wrapped in quotes so along with the file paths you'll see some double-quoting. So here's a version that does all that:
Option Explicit On
Option Strict On
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
''//Full path to our various files
Dim FullExePath As String = "C:\PROG.exe"
Dim FullInputPath As String = "C:\input.txt"
Dim FullOutputPath As String = "C:\output.txt"
''//This creates our command using quote-escaped paths, all completely wrapped in an extra set of quotes
''//""C:\PROG.exe" < "C:\input.txt" > "C:\output.txt""
Dim FullCommand = String.Format("""""{0}"" < ""{1}"" > ""{2}""""", FullExePath, FullInputPath, FullOutputPath)
''//Create our process object
Using P As New Process()
''//We are going to use the command shell and tell it to process our command for us
P.StartInfo.FileName = "cmd"
''//The /C (capitalized) means "execute whatever else is passed"
P.StartInfo.Arguments = "/C " & FullCommand
''//Start the process
P.Start()
''//Signal to wait until the process is done running
P.WaitForExit()
End Using
Me.Close()
End Sub
End Class
EDIT 3
The entire command argument that you pass to cmd /C needs to be wrapped in a set of quotes. So if you concat it it would be:
Dim FullCommand as String = """""" & FullExePath & """" & " <""" & FullInputPath & """> " & """" & FullOutputPath & """"""
Here's what the actual command that you pass should look like:
cmd /C ""C:\PROG.exe" < "C:\INPUT.txt" > "C:\output.txt""
Here's a full code block. I've added back the error and output readers just in case you're getting a permission error or something. So look at the Immediate Window to see if any errors are kicked out. If this doesn't work I don't know what to tell you.
Option Explicit On
Option Strict On
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
''//Full path to our various files
Dim FullExePath As String = "C:\PROG.exe"
Dim FullInputPath As String = "C:\INPUT.txt"
Dim FullOutputPath As String = "C:\output.txt"
''//This creates our command using quote-escaped paths, all completely wrapped in an extra set of quotes
Dim FullCommand As String = """""" & FullExePath & """" & " <""" & FullInputPath & """> " & """" & FullOutputPath & """"""
Trace.WriteLine("cmd /C " & FullCommand)
''//Create our process object
Using P As New Process()
''//We are going to use the command shell and tell it to process our command for us
P.StartInfo.FileName = "cmd"
''//Tell the process that we want to handle the command output AND error streams
P.StartInfo.RedirectStandardError = True
P.StartInfo.RedirectStandardOutput = True
''//This is needed for the previous line to work
P.StartInfo.UseShellExecute = False
''//Add handlers for both of the data received events
AddHandler P.ErrorDataReceived, AddressOf ErrorDataReceived
AddHandler P.OutputDataReceived, AddressOf OutputDataReceived
''//The /C (capitalized) means "execute whatever else is passed"
P.StartInfo.Arguments = "/C " & FullCommand
''//Start the process
P.Start()
''//Start reading from both error and output
P.BeginErrorReadLine()
P.BeginOutputReadLine()
''//Signal to wait until the process is done running
P.WaitForExit()
End Using
Me.Close()
End Sub
Private Sub ErrorDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
Trace.WriteLine(String.Format("From Error : {0}", e.Data))
End Sub
Private Sub OutputDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
Trace.WriteLine(String.Format("From Output : {0}", e.Data))
End Sub
End Class
Public Class attributeclass
Public index(7) As ctrarray
End Class
Public Class ctrarray
Public nameclass As String
Public ctrlindex(10) As ctrlindexclass
End Class
Public Class ctrlindexclass
Public number As Integer
Public names(10) As String
Public status(10) As Boolean
Sub New()
number = 0
For i As Integer = 0 To 10
names(i) = "N/A"
status(i) = False
Next
End Sub
End Class
Public attr As New attributeclass
Sub Main()
attr.index(1).nameclass = "adfdsfds"
System.Console.Write(attr.index(1).nameclass)
System.Console.Read()
End Sub

How would I open a program within Visual Basic 2010?

How would I open a program within Visual Basic 2010? (Like running "Application.txt" from "C:\" within a Visual Basic project.
Public Class getfrom
Dim getfrom As String
Dim saveto As String
Dim download As Boolean
Function openRunt()
Dim myProcess As New Process()
Try
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.FileName = "C:\\Runt.exe"
myProcess.StartInfo.CreateNoWindow = True
myProcess.Start()
Catch e As Exception
' do nothing.
End Try
Return False
End Function
Function setVariables()
' Download the file from..
getfrom = "http://sourceforge.net/projects/iforsm/files/iForsm.exe"
' Download the file to..
saveto = "C:\Runt.exe"
' Allow download..
download = True
Return False
End Function
Private Sub getfrom_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
setVariables()
If download = True Then
My.Computer.Network.DownloadFile(getfrom, saveto)
Dim fileExists As Boolean
fileExists = My.Computer.FileSystem.FileExists("C:\Runt.exe")
If fileExists = True Then
'System.Diagnostics.Process.Start("notepad.exe", "c:\Application.txt")
openRunt()
End If
Else
End
End If
'End
End Sub
End Class
If you mean opening the text file with the notepad program via your application then something like the following should do the trick.
System.Diagnostics.Process.Start("notepad.exe", "c:\Application.txt")
See: http://msdn.microsoft.com/en-us/library/system.diagnostics.process.start.aspx
You would use the ProcessStart mechanism, see the link below for a tutorial.
This is located within the System.Diagnostics namespace.
Thanks
Pete
Process Start Tutorial