Hey guys, its me again.

I think that wasn't 10 minutes since my last post :)

Now is another thing. I run a external app that has exit codes, it is all in its own documentation.

How can I get these codes inside my app?

And, can I add this same executable to my app exe (embed it) and run it? Like, extract to a temp folder, run it and then delete it when program closes?

Thanks again :D

Recommended Answers

All 18 Replies

No one can help me in this case? I really want to figure it out, but alone I can't :D

here is a small example which should give you an idea how to do it...

Module Module1

	Sub Main()
		Dim myProc As New Process()
		With myProc
			.StartInfo.FileName = "notepad.exe"
			.EnableRaisingEvents = True
			AddHandler .Exited, AddressOf MyProc_Exited
			.Start()
		End With
		Console.Read
	End Sub

	Private Sub MyProc_Exited(sender As Object, e As EventArgs)
		Console.WriteLine(CType(sender, Process).ExitCode)
	End Sub

End Module

Well, I've read it...

and didn't understood a letter :P I'm some kind of new to programming, almost everything I know is self-learned, so give a hand :)

ok...

Dim myProc As New Process() 'create a new process
		With myProc
			.StartInfo.FileName = "notepad.exe" 'set the executable (if needed add the path aswell)
			.EnableRaisingEvents = True 'have to be enabled in order to catch the process exit
			AddHandler .Exited, AddressOf MyProc_Exited 'add a handler for the exit of the process
			.Start() 'start the process
		End With

'this is the handler for the exit of the process
Private Sub MyProc_Exited(sender As Object, e As EventArgs)
'writes the exit code of the process
		Console.WriteLine(CType(sender, Process).ExitCode)
	End Sub

more clear?

Oh yeah, now I got it. I'll try it later, now I had to go to work. maybe tomorrow I'll be able to reply if it worked.

thanks anyway! (:

Hm... I think I got the main idea, but I didn't figured out on how to use it in my project.

Here's the code:

Public Class Main
    Dim NomedoBackup As String
    Dim Argumentos As String
    Dim Perfil As String = Environment.GetEnvironmentVariable("UserProfile")
    Dim Executavel As String

    Private Sub Procurar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Procurar.Click

        Dim Salvar As New SaveFileDialog()

        Salvar.InitialDirectory = "c:\"

        If SFX.Checked = True Then

            Salvar.Filter = "Executáveis|*.exe"

        Else

            Salvar.Filter = "Arquivos zip (*.zip)|*.zip|Arquivos rar (*.rar)|*.rar|Arquivos 7zip (*.7z)|*.7z"

        End If

        If Salvar.ShowDialog() = DialogResult.OK Then

            NomedoBackup = Salvar.FileName
            Caminho.Text = NomedoBackup

        End If

    End Sub

    Private Sub Backup_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Backup.Click

        If Caminho.Text <> SalvarArquivo.FileName Then

            NomedoBackup = Caminho.Text

        Else

            NomedoBackup = SalvarArquivo.FileName

        End If

        If SFX.Checked = True Then

            Executavel = " -sfxout32.sfx + options.txt "

        Else

            Executavel = " "

        End If

        Argumentos = "a" & Executavel & NomedoBackup & " " & Chr(34) & Perfil & "\AppData\Local\Criterion Games\" & Chr(34)

        Process.Start("7za.exe", Argumentos)
    End Sub

    Private Sub Main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Me.FormBorderStyle = Windows.Forms.FormBorderStyle.FixedSingle

    End Sub

    Private Sub OneClickBackup_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OneClickBackup.CheckedChanged

        If OneClickBackup.CheckState = CheckState.Checked Then

            SFX.Enabled = False
            Caminho.Enabled = False
            Procurar.Enabled = False

        ElseIf OneClickBackup.CheckState = CheckState.Unchecked Then

            SFX.Enabled = True
            Caminho.Enabled = True
            Procurar.Enabled = True

        End If

        If OneClickBackup.Checked = False Then

            Argumentos = "a" & Executavel & Perfil & "\Desktop\Perfil.7z" & " " & Chr(34) & Perfil & "\AppData\Local\Criterion Games\" & Chr(34)

        Else

            Argumentos = "a" & Executavel & NomedoBackup & " " & Chr(34) & Perfil & "\AppData\Local\Criterion Games\" & Chr(34)

        End If

    End Sub
End Class

How can I implement this? :P

replace
Process.Start("7za.exe", Argumentos)
with:

Dim myProc As New Process()
		With myProc
			.StartInfo.FileName = "7za.exe" 'maybe the file path is needed
			.StartInfo.Arguments = Argumentos
			.EnableRaisingEvents = True
			AddHandler .Exited, Sub(pro As Object, ev As EventArgs)
							MsgBox("exit code: " & CType(pro, Process).ExitCode)
						End Sub
			.Start()
		End With

Thats it! Perfect, worked flawlessy. Thanks you very much for the help!

One more thing... how can I embed the 7za.exe into my app exe and run it from there? Or extract it to a temp path and run it?

Thanks again!

ok here is a example

Private Sub installFiles()

        Dim resFiles() As String = Application.ResourceAssembly.GetManifestResourceNames

        For Each resFile As String In resFiles
            If resFile.EndsWith("7za.exe") Then
                Dim tmpFile As String = IO.Path.Combine(IO.Path.GetTempPath, IO.Path.GetTempFileName)
              if  ExtractEmbeddedResourcefile then(Application.ResourceAssembly.GetManifestResourceStream(resFile), tmpFile)
                debug.writeline(tmpFile) 'do something with the file name here (like start your process)
             end if
               'delete file when done
                    IO.File.Delete(tmpFile)
               

            End If
        Next

    End Sub

    Private Function ExtractEmbeddedResourcefile(ByVal resStream As IO.Stream, ByVal OutFilename As String) As Boolean

        Try

            If IO.File.Exists(OutFilename) Then
                IO.File.Delete(OutFilename)
            End If

            Dim count As Integer = CType(resStream.Length, Integer) - 1
            Dim buffer(count) As Byte
            resStream.Read(buffer, 0, count + 1)

            Using fs As New FileStream(OutFilename, FileMode.Create)
                With fs
                    .Write(buffer, 0, count + 1)
                    .Flush()
                    .Close()
                End With
            End Using

            Return CBool(IO.File.Exists(OutFilename))
        Catch ex As Exception
            Return False
        End Try
        Return False
    End Function

Wow! Well, if I really got it...

I don't need to change anything on the function, right? All I need to do is change the part you commented.

Just another thing. I promise this will be the last one. I want that it extract everything that it needs when it loads. It would be nice to show an progress-bar, but not needed. And only delete everything when it closes.

If I got it, I can simply move

IO.File.Delete(tmpFile)

To:

Private Sub Main_Close(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.FormClosed

IO.File.Delete(tmpFile)

    End Sub

?

A progressbar would be useless as the extract of a file is very fast (except you try to extract a 200+MB file)
if you want to delete the file on form close then you have to declare tmpFile as global variable. But i really suggest to delete the file straight when its not needed anymore. Reason is simple...IF you app is crashing at any point this extracted resource get not deleted.

Sure that it will be useless, but I'm thinking on doing more apps to me that will handle large files (: this will answer another question to me :D

I thought on deleting it only on form close cause it might get used more than one time. Even if it has a fast extraction, I don't think that is nice to extract it every time it needs to be used.

And, to call a function, what do I need to do? I like to keep my codes clean and easy to understand, so I think that placing this code inside a function will make things more understandable.

The code you provided didn't worked.

When I pasted it on my code, it showed me some errors. I've tried to fix them, without sucess. Even changed my project from framework 2.0 to framework 4.0. Imported System.IO and System.Windows and still nothing.

Did I do something wrong?

it would help to know what errors you get.
Im still not a mind reader

Haha, sorry! Forgot it!

I got the following errors:
'ResourceAssembly' is not a member of 'System.Windows.Forms.Application'.

Argument not specified for parameter 'OutFilename' of 'Private Function ExtractEmbeddedResourcefile(resStream As System.IO.Stream, OutFilename As String) As Boolean'.

Argument not specified for parameter 'resStream' of 'Private Function ExtractEmbeddedResourcefile(resStream As System.IO.Stream, OutFilename As String) As Boolean'.

Syntax error. If ExtractEmbeddedResourcefile [B]then(Application[/B].ResourceAssembly.GetManifestResourceStream(resFile), tmpFile) 'tmpFile' is not declared. It may be inaccessible due to its protection level.

'End If' must be preceded by a matching 'If'.

:P

Private Sub installFiles()

		Dim resFiles() As String = System.Reflection.Assembly.GetExecutingAssembly.GetManifestResourceNames	

		For Each resFile As String In resFiles
			If resFile.EndsWith("7za.exe") Then
				Dim tmpFile As String = IO.Path.Combine(IO.Path.GetTempPath, IO.Path.GetTempFileName)
				If ExtractEmbeddedResourcefile(System.Reflection.Assembly.GetExecutingAssembly.GetManifestResourceStream(resFile), tmpFile) Then
					Debug.WriteLine(tmpFile) 'do something with the file name here (like start your process)
				End If
				'delete file when done
				IO.File.Delete(tmpFile)
			End If
		Next

	End Sub

	Private Function ExtractEmbeddedResourcefile(ByVal resStream As IO.Stream, ByVal OutFilename As String) As Boolean

		Try

			If IO.File.Exists(OutFilename) Then
				IO.File.Delete(OutFilename)
			End If

			Dim count As Integer = CType(resStream.Length, Integer) - 1
			Dim buffer(count) As Byte
			resStream.Read(buffer, 0, count + 1)

			Using fs As New IO.FileStream(OutFilename, IO.FileMode.Create)
				With fs
					.Write(buffer, 0, count + 1)
					.Flush()
					.Close()
				End With
			End Using

			Return CBool(IO.File.Exists(OutFilename))
		Catch ex As Exception
			Return False
		End Try
	End Function

I'll try it as soon as I can.

Sorry for the late response, I wasn't at home and was not able to use my computer (:

Its been a while since this has been posted... Almost immediately I've asked this, I've found an alternate solution: DotNetZip - http://dotnetzip.codeplex.com/

I haven't tested this, but seems nice to have in database!

Thanks for everyone that helped.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.