Capture 7-Zip output and exit code from a process in VB - vb.net

I have the following VB.NET 4.0 console application that runs 7z.exe in a process and successfully completes with a zipped file:
Public Sub CompressFiles(sZipFileName As String, sDriveLetter As String)
Dim s7ZipCmdArgs As String = ""
Dim myProcess As New Process
Console.WriteLine()
Console.WriteLine("Scanning files...")
'Compress files
s7ZipCmdArgs = " a -r -y -xr!windows\ -xr!$Recycle.Bin\ " + sZipFileName _
+ " " + sDriveLetter + "\*.txt" _
+ " " + sDriveLetter + "\*.doc" _
+ " " + sDriveLetter + "\*.xls" _
+ " " + sDriveLetter + "\*.ppt" _
+ " " + sDriveLetter + "\*.url" _
+ " " + sDriveLetter + "\*.docx" _
+ " " + sDriveLetter + "\*.xlsx" _
+ " " + sDriveLetter + "\*.pptx" _
+ " " + sDriveLetter + "\*.pdf" _
+ " " + sDriveLetter + "\*.wav" _
+ "> C:\test\zipresults.txt"
myProcess.StartInfo.FileName = "C:\test\7-Zip\7z.exe"
myProcess.StartInfo.Arguments = s7ZipCmdArgs
myProcess.StartInfo.WorkingDirectory = "C:\test"
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.CreateNoWindow = True
myProcess.Start()
myProcess.WaitForExit()
End Sub
The code executes fine except for the redirect to a text file: "> C:\test\zipresults.txt" in the s7ZipCmdArgs string variable. I'm not sure why that's not working, I've tried different sets of double and triple quotes without success. It does work in a batch file using the same string.
My second question is: How do I capture the 7Zip exit code so that I can determine if it completed successfully? It returns the following integers: 0 (No errors), 1 (Non fatal error), 2 (Fatal error), 7 (Command line error), 8 (Memory error), and 255 (User error). I'm not sure how to capture the integer so that I can decode it.

For the first part, have you tried adding a space before the > in your command args? You could also check out this answer for capturing the output in code.
For the first part, per this answer you can't redirect the standard output using > when using Process.Start(). So, you will need to remove the redirect from the arguments, set StartInfo.RedirectStandardOutput to true, and then write the output to a file in the OutputDataReceived event. Something like this:
Dim pgm = "C:\Program Files\7-Zip\7z.exe"
Dim args = "l C:\Dev\Test.zip"
Dim myProcess = New Process()
With myProcess.StartInfo
.FileName = pgm
.Arguments = args
.WorkingDirectory = "C:\Dev"
.UseShellExecute = False
.CreateNoWindow = True
.RedirectStandardOutput = True
End With
Using out = New StreamWriter("C:\Dev\test.txt")
AddHandler myProcess.OutputDataReceived,
Sub(sender, e)
out.WriteLine(e.Data)
End Sub
myProcess.Start()
myProcess.BeginOutputReadLine()
myProcess.WaitForExit()
End Using
For the second, myProcess.ExitCode will have the result after the WaitForExit() call.

Related

Dont get returned list of files in temp folder on Domino server via agent

I have a LotusScript agent, signed with proper ID to have full access rights on server. The agent should return a list of files in the temporary folder. Ultimately I would this agent to clean a specific folder here.
The problem is that the agent does not return a list of files although I know that files are there!
I wondering if I am dealing with some form of restriction (and how to pass by it) or if my code is incorrect (how to correct it).
The code is mostly inspired by in IBM support note.
https://www.ibm.com/support/pages/using-dir-function-recursive-lotusscript
Here is the code
Comment: [Not Assigned]
Shared Agent: Yes
Type: LotusScript
State: Disabled
Trigger: Scheduled
Interval: On Schedule More Than Once A Day
Acts On: None
LotusScript Code:
%REM
Agent cleanupTempCatalogAlt2
Created Sep 13, 2019 by §Patrick §Kwinten/Designer/ACME
Description: Comments for Agent
%END REM
Option Public
Option Declare
Dim sess As NotesSession
Dim agent As NotesAgent
Sub Initialize
Dim sess As New NotesSession
Set agent = sess.CurrentAgent
Print("### PK " + agent.Name + " - Starting ")
ScanDirs("D:\IBM\Domino\Temp\notes53F5BD\xspupload")
End Sub
Sub ScanDirs(path As String)
Print("### PK " + agent.Name + " - Start ScanDirs")
Dim sess As New NotesSession
Dim DirList As Variant
Dim filename As String
Dim filepath As String
Dim sep As String
If path <> "" Then
If InStr(sess.Platform, "Windows") > 0 Then
sep = "\"
Else
sep = "/"
End If
ReDim DirList(0)
If InStr(path, sep) > 0 Then
filepath = StrLeftBack(path, sep)
End If
Print("### PK " + agent.Name + " filepath - " + filepath)
Print("### PK " + agent.Name + " path - " + path)
filename = Dir(path, 16)
While filename <> ""
Print("### PK " + agent.Name + " filename - " + filename)
If filename <> "." And filename <> ".." Then
Print("### PK " + agent.Name + " filepath & sep & filename - " + filepath & sep & filename)
If (GetFileAttr(filepath & sep & filename) And 16) > 0 Then
DirList = ArrayAppend(DirList,filepath & sep & filename & sep)
Else
Print("### PK " + agent.Name + " - Got file?")
' PERFORM DESIRED CHECK/OPERATION
' ON filepath & sep & filename
' OR filename (as desired)
End If
End If
filename = Dir
Wend
Print("### PK " + agent.Name + " DirList - " + DirList(0))
DirList = FullTrim(DirList)
ForAll dirpath In DirList
ScanDirs(dirpath)
End ForAll
End If
End Sub
Try setting "Runtime security level" to 2 or 3 in agent properties.
Which version of Domino you are running and what platform?
Could the problem be here:
https://www-01.ibm.com/support/docview.wss?uid=swg1LO78281
upgrading to SLES11, the "dir$" function in LotusScript does
not see
directories and files within mounted shares anymore.
We didn't have chance to change linux-version so the problem was solved by syncing folder to server. Thereby we could remove files, and syncing takes care of the rest.

Remote desktop connection using process.startinfo

I have created an asp.net webpage and from the webpage I am using the code below to establish a remote desktop connection.
rdp.exe is a external file
Here is my code
Protected Sub BtnRemote_Click(ByVal sender As Object, ByVal e As EventArgs) Handles BtnRemote.Click
Dim Process As New System.Diagnostics.Process
Dim startinfo As New System.Diagnostics.ProcessStartInfo
startinfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
startinfo.FileName = "C:\WINDOWS\system32\cmd.exe"
Dim path = "D:\rdp.exe"
startinfo.Arguments = path + "/v:" + txtTerminal.Text + " " + "/u:" + txtTerUser.Text + " " + "/p:" + txtTerPassword.Text
startinfo.UseShellExecute = False
Process.Start(startinfo)
End Sub
Everything is fine when I debug, but the system will not establish a remote connection.
But if I use the following command from command prompt, I am able to establish a remote connection.
E:\rdp /v:"IPAddress" /domain:"domain" /u:"username" /p:"password"
A problem i can see with this is within this line (Also Notice its got the Path, User, Password, and IP, BUT is missing the Domain Argument):
startinfo.Arguments = path + "/v:" + txtTerminal.Text + " " + "/u:" + txtTerUser.Text + " " + "/p:" + txtTerPassword.Text
as stated in your CMD arguments it needs to fit this format:
E:\rdp /v:"IPAddress" /domain:"domain" /u:"username" /p:"password"
However if you notice your startinfo.arguments doesn't contain a space in between the Directory and the IP Address Line so instead of reading it like this:
E:\rdp /v:"IPAddress" /u:"username" /p:"password"
it's reading it like this:
E:\rdp/v:"IPAddress" /u:"username" /p:"password"
just simply fix the line like this:
startinfo.Arguments = path + " /v:" + txtTerminal.Text + " /u:""" + txtTerUser.Text + """ /p:" + txtTerPassword.Text
I Also removed the Concatenations of + " " + because all you really need is a
space before the /'s and it will still work properly. Also notice that i have added extra quotes, because if the username supports spaces then when it goes to set the argument if the username contains a space then it will count them as two separate arguments quotes around it prevents it from being split into two different arguments
also instead of using CMD why not start the exe directly by
Dim p As Process
p.startinfo.FileName = "D:\rdp.exe"
p.StartInfo.WorkingDirectory = "D:\"
startinfo.Arguments = path + " /v:" + txtTerminal.Text + " /u:""" + txtTerUser.Text + """ /p:" + txtTerPassword.Text
p.Start()

Visual Basic - Cannot access file because used by another process even after closed file

My script automatically uploads a text file after being created and editted through the program. The creating and editting (appending) works fine, but when the exe reaches the line where the file is uploaded, I get the error:
Cannot access file because used by another process
The file is being closed and disposed before uploading, but that doesn't matter. Even after some google searches I can't find the problem and solution.
I use the following code to create and append the text.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles BtnAdd.Click
Try
Using file As New System.IO.StreamWriter(currentdir + "\logs\" + FormClient.gametitle + "." + FormLogin.username + "_" + thisDate + "_ [" + fileNumber + "]" + ".txt", True)
file.WriteLine(TxtIssue.Text + " " + TxtWhen.Text + " " + TxtWhere.Text + " " + TxtInfo.Text)
file.WriteLine("")
End Using
Catch ex As Exception
MessageBox.Show(("Error while loading: " + ex.Message))
End Try
End Sub
Private Sub FormFeedback_Closing(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles MyBase.FormClosing
thisDate = Today
Dim filenameFormat = currentdir + "\logs\" + FormClient.gametitle + "." + FormLogin.username + "_" + thisDate + "_ [" + fileNumber + "]" + ".txt"
Dim uploadFormat = Path.Combine("-removed-", filenameFormat)
My.Computer.Network.UploadFile(filenameFormat, uploadFormat, "mennovv", "mennomail98", True, 500)
End Sub
The following piece of code checks if a file exists, but I don't think this is the problem.
While My.Computer.FileSystem.FileExists(currentdir + "\logs\" + FormClient.gametitle + "." + FormLogin.username + "_" + thisDate + "_ [" + fileNumber + "]" + ".txt") = True
fileNumber += 1
End While

Image location won't write to file and Image won't load from file location

well I want to make the program write a an image location to a text file, and then when the user presses the "load" button, it reads that image location and sets it as the Image of the PictureBox, but so far I have had no success at all.
Private Sub Btn_Save_Click(sender As Object, e As EventArgs) Handles Btn_Save.Click
Dim path As String = My.Computer.FileSystem.SpecialDirectories.MyPictures + "\Card Library\Configs\" + "config_card.aygo"
Dim path2 As String = My.Computer.FileSystem.SpecialDirectories.MyPictures + "\Card Library\Configs\" + "set_cardimg.aygo"
' Create or overwrite the file.
Dim fs As FileStream = File.Create(path)
Dim fs2 As FileStream = File.Create(path2)
' Add text to the file.
Dim info As Byte() =
New UTF8Encoding(True).GetBytes(
"----------Saved Card Settings----------" + vbNewLine +
"Level: " + My.Settings.Level.ToString + vbNewLine +
"NoMonster: " + My.Settings.NoMonster.ToString + vbNewLine +
"Spell: " + My.Settings.Spell.ToString + vbNewLine +
"Trap: " + My.Settings.Trap.ToString + vbNewLine +
"XYZLevel: " + My.Settings.XyzLevel.ToString + vbNewLine +
"ATKValue: " + My.Settings.ATKValue.ToString + vbNewLine +
"DEFValue: " + My.Settings.DEFValue.ToString + vbNewLine +
"AttributeID: " + My.Settings.AttributeID.ToString + vbNewLine +
"CardID: " + My.Settings.CardID.ToString)
fs.Write(info, 0, info.Length)
fs.Close()
Dim info2 As Byte() =
New UTF8Encoding(True).GetBytes(CardImage.InitialImage.ToString)
fs2.Write(info2, 0, info2.Length)
fs2.Close()
MsgBox("Configuration saved successfully!", vbInformation)
End Sub
Private Sub Btn_Load_Click(sender As Object, e As EventArgs) Handles Btn_Load.Click
Dim path As String = My.Computer.FileSystem.SpecialDirectories.MyPictures + "\Card Library\Configs\" + "config_card.aygo"
Try
My.Settings.Level = CInt(GetSettingItem(path, "level"))
My.Settings.NoMonster = CInt(GetSettingItem(path, "nomonster"))
My.Settings.Spell = CBool(GetSettingItem(path, "spell"))
My.Settings.Trap = CBool(GetSettingItem(path, "trap"))
If My.Settings.NoMonster = 1 Then
If My.Settings.Spell = True Then
CardFt.Card_Spell()
Else
If My.Settings.Trap = True Then
CardFt.Card_Trap()
Else
CardFt.Card_Legendary()
End If
End If
End If
My.Settings.XyzLevel = CInt(GetSettingItem(path, "xyzlevel"))
If My.Settings.XyzLevel = 1 Then
CardFt.Card_XYZ()
End If
My.Settings.ATKValue = GetSettingItem(path, "atkvalue")
ATKText.Text = GetSettingItem(path, "atkvalue")
My.Settings.DEFValue = GetSettingItem(path, "defvalue")
DEFText.Text = GetSettingItem(path, "defvalue")
My.Settings.AttributeID = CInt(GetSettingItem(path, "attributeid"))
If My.Settings.AttributeID = 1 Then
AttributeLayer.Image = My.Resources.Earth
ElseIf My.Settings.AttributeID = 2 Then
AttributeLayer.Image = My.Resources.Water
ElseIf My.Settings.AttributeID = 3 Then
AttributeLayer.Image = My.Resources.Fire
ElseIf My.Settings.AttributeID = 4 Then
AttributeLayer.Image = My.Resources.Wind
ElseIf My.Settings.AttributeID = 5 Then
AttributeLayer.Image = My.Resources.Dark
ElseIf My.Settings.AttributeID = 6 Then
AttributeLayer.Image = My.Resources.Light
ElseIf My.Settings.AttributeID = 7 Then
AttributeLayer.Image = My.Resources.Divine
End If
My.Settings.CardID = CInt(GetSettingItem(path, "cardid"))
CardFt.Card_Loader()
If My.Computer.FileSystem.FileExists(My.Computer.FileSystem.SpecialDirectories.MyPictures + "\Card Library\Configs\" + "set_cardimg.aygo") Then
Try
Dim fileReader As String
fileReader = My.Computer.FileSystem.ReadAllText(My.Computer.FileSystem.SpecialDirectories.MyPictures + "\Card Library\Configs\" + "set_cardimg.aygo")
Catch ex As Exception : End Try
End If
Dim bitmap As New Bitmap(My.Computer.FileSystem.SpecialDirectories.MyPictures + "Card Library\Configs\" + "set_cardimg.aygo")
CardImage.Image = CType(bitmap, System.Drawing.Image)
Catch ex As Exception
MsgBox("An error occured while loading the configuration file: " & vbNewLine & ex.Message & vbNewLine & vbNewLine & ex.ToString, vbExclamation)
My.Computer.Clipboard.SetText(ex.ToString)
End Try
End Sub
The error that I get from this is:
System.ArgumentException: Parameter is not valid.
at System.Drawing.Bitmap..ctor(String filename)
at AnimeYuGiOhCardMaker.CardMaker.Btn_Load_Click(Object sender, EventArgs e) in C:\Users\Compusys\Documents\Visual Studio 2012\Projects\Anime Yu-Gi-Oh Card Maker\Anime Yu-Gi-Oh Card Maker\Form1.vb:line 521
Now then, when the Save Button is being pressed It does not write the image location to file however it writes the following:
System.Drawing.Bitmap
This is why I get the error above.
The actual error is from here:
Dim bitmap As New Bitmap(My.Computer.FileSystem.SpecialDirectories.MyPictures + "Card Library\Configs\" + "set_cardimg.aygo")
CardImage.Image = CType(bitmap, System.Drawing.Image)
The error occurs even with an actual file path.
I tried a few different ways but none of them worked. Any help would be really appreciated. Thanks.
--
Dom
The original question has changed several times, including the exception. The current state of the question has several problems, the main one being this:
If My.Computer.FileSystem.FileExists(My.Computer.FileSystem.SpecialDirectories.MyPictures + "\Card Library\Configs\" + "set_cardimg.aygo") Then
Try
Dim fileReader As String
fileReader = My.Computer.FileSystem.ReadAllText(My.Computer.FileSystem.SpecialDirectories.MyPictures _
+ "\Card Library\Configs\" + "set_cardimg.aygo")
' EMPTY CATCH !!!!!!
Catch ex As Exception : End Try
End If
Dim bitmap As New Bitmap(My.Computer.FileSystem.SpecialDirectories.MyPictures _
+ "Card Library\Configs\" + "set_cardimg.aygo")
CardImage.Image = CType(bitmap, System.Drawing.Image)
set_cardimg.aygo is just a config file which contains some text. it is not a valid image file, so you cannot create a bitmap from it.
You should open that file, read the contents into a variable, then if it is a valid location, create the bitmap from it, or better just set the picturebox .Location and let it load the image without you creating a bitmap first.

vb.net Cannot find file specified ""C:\Users""

What I want to do is when I click button2 it runs a cmd command which is
attrib +s +h "Path here", but it says it can't find specified ""Path here""
This is my Code:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
If NotHidden.SelectedIndex >= 0 Then
LogsKeeper.Text = LogsKeeper.Text + TimeOfDay + " | " + "Moved To Hidden: " + NotHidden.SelectedItem.ToString + vbNewLine
Hidden.Items.Add(NotHidden.SelectedItem)
Dim path As String = NotHidden.SelectedItem
My.Settings.TempPath = path
Process.Start("cmd /C " + "attrib +s +h " + My.Settings.TempPath)
NotHidden.Items.Remove(NotHidden.SelectedItem)
WriteTextToLogs()
MsgBox("Folder is hidden now. if you want to delete it then you need to move it to NotHidden first ")
HiddenFolders.Text = HiddenFolders.Text + NotHidden.SelectedItem + vbNewLine
My.Settings.HiddenFolders = HiddenFolders.Text
My.Settings.Save()
Else
MsgBox("You need to select a path first")
End If
End Sub
And how I add folders to listbox Hidden:
Private Sub AddFolder()
If SecretFolderPath.Text.Length > 0 Then
SecretFolderPath.Text = """" + SecretFolderPath.Text + """"
LogsKeeper.Text = LogsKeeper.Text + TimeOfDay + " | " + SecretFolderPath.Text + vbNewLine
My.Settings.Logs = LogsKeeper.Text
My.Settings.Save()
LogsKeeper.Text = My.Settings.Logs
Logs.Items.Clear()
NotHidden.Items.Add(SecretFolderPath.Text)
For Each line As String In LogsKeeper.Lines
Logs.Items.Add(line)
Next
SecretFolderPath.Clear()
MsgBox("Folder Added!")
Else
MsgBox("Folder path is not correct ")
End If
End Sub
I need to Execute command : attrib +s +h "Path here", but it says it can find file specified ""Path here"" and I need the double single quotes to run the command.
This is more complicated but definitely does the trick:
Dim p As Process = New Process()
Dim pi As ProcessStartInfo = New ProcessStartInfo()
pi.Arguments = " /C attrib +s +h " + My.Settings.TempPath
pi.FileName = "cmd.exe"
p.StartInfo = pi
p.Start()