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

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.

Related

Check if file exists and copy it if it does

I've been searching the net and have tried all the code found. My code should be simple but it's not working. I'm using a list to store image strings (but they do not have the extension on them). I want to test if the image file exists in a folder and if it does copy it. If it doesn't write to a file with the image name. The result I'm getting is all the files do not exists. But I checked and the files are there.
For Each image In GraphicList
ImgFile = ImgLocation & "\" & image & ".*"
Dim MoveFile As String
MoveFile = createFigFolder & "\" & image & ".*"
If Not System.IO.File.Exists(ImgFile) Then
Debug.Write("File does not exists : " & ImgFile & vbCrLf)
' file does not exist
Else
Debug.Write("File EXISTS : " & ImgFile & vbCrLf)
System.IO.File.Copy(ImgFile, MoveFile)
End If
Next
Here's the code that writes the GraphicList
Private Sub CreateGraphicsFunction(sender As Object, e As EventArgs)
Dim Regex = New Regex("infoEntityIdent=""(ICN.+?)[""].*?[>]")
Dim ICNFiles = Directory.EnumerateFiles(MoveToPath, "*.*", SearchOption.AllDirectories)
For Each tFile In ICNFiles
Dim input = File.ReadAllText(tFile)
Dim match = Regex.Match(input)
If match.Success Then
GraphicList.Add(match.Groups(1).Value)
Dim Regex2 = New Regex("<!ENTITY " & match.Groups(1).Value & " SYSTEM ""(ICN.*?[.]\w.+)")
Dim sysFileMatch = Regex2.Match(input)
If sysFileMatch.Success Then
ICNList.Add(sysFileMatch.Groups(1).Value)
Debug.Write("found ICN " & sysFileMatch.Groups(1).Value)
End If
End If
Next
End Sub
New Code to cycle through array and see if its entries match strings in Graphic Lists. This code doesn't work, but I think it's similar to what I want.
Dim fileEntries As String() = Directory.GetFiles(ImgLocation, ".*")
' Process the list of files found in the directory. '
Dim fileName As String
For Each fileName In fileEntries
If ICNList.Contains(fileName) Then
Debug.Write("File EXISTS : " & fileName & vbCrLf)
Else
Debug.Write("File does not exists : " & fileName & vbCrLf)
End If
Next
Join the list of filenames on the source list of files, using the filename without extension as the key. Then iterate over the results and copy each one
Dim fileNames = System.IO.Directory.GetFiles(imgLocation).Join(
graphicList,
Function(p) Path.GetFileNameWithoutExtension(p),
Function(f) f,
Function(p, f) p)
' create the directory first (does nothing if it already exists)
Directory.CreateDirectory(newLocation)
' copy each file
For Each fileName In fileNames
System.IO.File.Copy(fileName, Path.Combine(newLocation, Path.GetFileName(fileName)))
Next

How to terminate a process if it has specific folder name in its path?

I run an application from PowerBuilder and terminate it when i dont need it. But the application when running, it executes other processes from a specific folder.
I want to kill all processes if they run from a specific folder.
How to get the process handles of all those processes that have specif folder name in their path?
Here an example to show how to terminate all running instance of Notepad.exe
OleObject wsh
integer li_rc
wsh = CREATE OleObject
wsh.ConnectToNewObject( "MSScriptControl.ScriptControl" )
wsh.language = "vbscript"
wsh.AddCode('function terminatenotepad() ~n ' + &
'strComputer = "." ~n ' + &
'Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") ~n ' + &
'Set colItems = objWMIService.ExecQuery("Select * from Win32_Process where name = ~'notepad.exe~'") ~n ' + &
'For Each objItem in colItems ~n ' + &
' objItem.Terminate ~n ' + &
'Next ~n ' + &
'end function ~n ' )
wsh.executestatement('terminatenotepad()')
wsh.DisconnectObject()
DESTROY wsh
Try to change the where clause
where name = ~'notepad.exe~'" ...
for
where commandline = ~'" + ls_commandline + "~'" ...
where ls_commandline is the command line used to start your process.
See "Win32_Process class" for more infos.
/// This is simple code example Terminate a Running Process if here is specific
/// folder name in the path of the running program (\EagleGet\)
/// Two variable SelectThis and TheWhere can be changed to get different
/// results. Many things are not dynamic in this script and certainly not the
/// best way of writing code. but its just ok for a little quick work.`
OleObject wsh
Integer li_rc
String LineFeed = ' ~r~n '
String TheComputer = "." //local computer
String TheCode = "no need to set it here"
String FunctionName = "Whatever()" //any name you like
String SelectThis = "?" //only the columns/expressions
String TheWhere = "?" //only the where clause without keyword WHERE
String DoWhat = "?" //the action to perform for example 'Terminate' without quotes
String TheQuery = "no need to set here"
String WMIClass = "Win32_Process" /// The WMI class of running processes
String TheFolderName = "The folder name from which the creapy process is running (path) "
/// You just set DoWhat, SelectThis and TheWhere. Rest of the variables, you dont need to set here
/// SelectThis = is the columns or expressions you want returned by the Query
SelectThis = "*"
/// TheFolderName = set it to the name of the folder that exist in the path
///of the ruuning process you want to terminate
TheFolderName = "EagleGet"
/// TheWhere is the WHERE clause expressions
TheWhere = "ExecutablePath LIKE ~'%\\" + TheFolderName + "\\%~' "
/// DoWhat is the final function call of the WMI Class
DoWhat = "Terminate"
/// There is no need to chage anything from this point onward.
/// without double quotes, and you dont have to change TheQuery here
TheQuery = " SELECT " + SelectThis + " FROM " + WMIClass + " WHERE " + TheWhere
TheCode = "Function " + FunctionName + LineFeed + &
"strComputer = ~"" + TheComputer + "~"" + LineFeed + &
"Set objWMIService = GetObject(~"winmgmts:\\~" & strComputer & ~"\root\cimv2~")" + LineFeed + &
"Set colItems = objWMIService.ExecQuery(~"" + Trim(TheQuery) + "~" )" + LineFeed + &
"For Each objItem in colItems" + LineFeed + &
"objItem." + Trim(DoWhat) + LineFeed + &
"Next " + LineFeed + &
"END Function " + LineFeed
wsh = CREATE OleObject
wsh.ConnectToNewObject("MSScriptControl.ScriptControl")
wsh.Language = "VBScript"
wsh.AddCode(TheCode)
TRY
wsh.ExecuteStatement(FunctionName)
CATCH (RunTimeError Re01)
MessageBox("Query Error", "Following code has some problems.~r~n~r~n" + TheCode, StopSign!)
END TRY
wsh.DisconnectObject()
DESTROY wsh

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

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

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.

Move files with certain extensions only

I'm currently using the Directory.Move method to copy files from one location to another. What i would like to do is only move files with certain extensions (.dbf, .ini & .txt). If the original folder doesn't contain any of these files then i just want to create an empty directory
Current code I'm using is...
Dim n As Integer
If lb1.SelectedItems.Count = 0 Then Exit Sub
For n = 0 To UBound(AllDetails)
If AllDetails(n).uName & " - " & AllDetails(n).uCode & " - " & AllDetails(n).uOps = lb1.SelectedItem Then
If Not My.Computer.FileSystem.DirectoryExists(aMailbox & "\" & AllDetails(n).uFile) Then
Directory.Move(zMailbox & AllDetails(n).uFile, aMailbox & "\" & AllDetails(n).uFile)
lb3.Items.Add(AllDetails(n).uName & " - " & AllDetails(n).uCode & " - " & AllDetails(n).uOps)
Else
lb3.Items.Add(AllDetails(n).uName & " - " & AllDetails(n).uCode & " - " & AllDetails(n).uOps)
Exit Sub
End If
End If
Next
All the variables are declared and this works but moves the entire folder contents
One way to approach this is to use each extension as a search pattern for File.GetFiles, then use Directory.Move on each file returned. Something like this might help:
For Each OldFile As String In (From s In {".dbf", ".ini", ".txt"}
From f In Directory.GetFiles(zMailbox & AllDetails(n).uFile, s)
Select f)
Directory.Move(OldFile, aMailbox & "\" & AllDetails(n).uFile & "\" & Path.GetFileName(OldFile))
Next
if what you want is certain file extensions only? well Open File Dialog can filter that for you
Let's say you call this operation with a button click:
Dim fd As OpenFileDialog = New OpenFileDialog()
fd.Title = "Open File Dialog"
fd.InitialDirectory = "the initial directory you want to look at first"
'this filters the available files to be opened!
fd.Filter = "dbf files|*.dbf*|ini files|*.ini*|Text files|*.txt*"
fd.FilterIndex = 2 'set's the default files to open first as .ini
fd.RestoreDirectory = True
If fd.ShowDialog() = Windows.Forms.DialogResult.OK Then
'Copy the file to the location using the copyer subroutin
resulta.Text = fd.FileName.ToString
Copyer(fd.FileName.Tostring, "the location where you want to copy")
End If
End Sub
Now for the copying of the file, have a look at this subroutine. This subroutine checks first if the file exists. If it does, it deletes it, then copies the new file.
Public Sub Copyer(ByVal theFile As String, ByVal Lokasyon As String)
Try
Dim resultpath As String = Lokasyon
If System.IO.File.Exists(resultpath) = True Then
System.IO.File.Delete(resultpath)
'this deletes the file so you can overwrite it.
End If
My.Computer.FileSystem.CopyFile(theFile, resultpath)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Please let me know if this has helped you.