sibon1
25th April 2003, 09:10
I have written my own program using native baan. you can see all active baan user by company; you can sort them by processID, UserID, LogonDate and Company; you also can kill a specific process or send a notice to a active user; if you wish, you can see the open sessions of a user.

enclosed pls. find a hardcopy of the session and the program script.

it works good and fast for me on Windows 2000 Server; i never tested it on Unix.

Josef N.

|******************************************************************************
|* tccom9590 0 VRC B40C c4 wuh1
|* *Aktive User abfragen
|* Nobis Josef
|* 2002-10-08
|******************************************************************************
|* Main table tccom990 Aktive User, Form Type 2
|* All Rights Reserved
|*
|* Permission to use, copy, modify, and distribute this software and its
|* documentation for any purpose and without fee is hereby granted,
|* provided that the above copyright notice appear in all copies and that
|* both that copyright notice and this permission notice appear in
|* supporting documentation.
|*
|* Josef N. and Baanboard.com DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|* AND FITNESS, IN NO EVENT SHALL Norbert Wimmer nor Baanboard.com BE LIABLE FOR ANY
|* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|* OR PERFORMANCE OF THIS SOFTWARE.
|******************************************************************************

|****************************** declaration section ***************************
declaration:

#pragma used dll ottdllbw

table ttccom990 | Aktive User
table tttaad200 | User

extern domain tcemno emno.f
extern domain tcemno emno.t

extern domain tcitem cprj.f fixed
extern domain tcitem cprj.t fixed
extern domain tcyrno year.f
extern domain tcyrno year.t
extern domain tcpern pern.f
extern domain tcpern pern.t
extern domain tcitem item.f fixed
extern domain tcitem item.t fixed
extern domain tcmcs.str30 filename
extern domain tcmcs.str50 filenamepath
extern domain tcmcs.str215 stringline
extern long ret
extern long file.pointer
extern long i
extern long fieldcounter
extern long item.exist
extern long rec.good
extern long rec.bad
extern domain tcmcs.str50 tempstr

extern domain tcitem item.i
extern domain tcqsl1 quan.i

extern domain tcmcs.str10 server.i
extern domain tcmcs.str15 user.pid
extern domain tcmcs.str12 user.i
extern domain tcmcs.long pid.i
extern domain tcmcs.str15 system.i
extern domain tcmcs.str10 date.i
extern domain tcmcs.str5 time.i
extern domain tcmcs.str16 date.time
extern domain tcqiv1 user.f1
extern domain tcqiv1 user.f2
extern domain tcqiv1 user.f3
extern domain tcqiv1 user.all

extern domain tcmcs.str50 i.file
extern domain tcmcs.str50 baan.message
extern domain tcmcs.str1 qm | Quotation Mark = "


|****************************** form section **********************************

form.1:
init.form:
daten.aktualisieren()

|# Schaltfläche Daten aktualisieren
choice.user.0:
before.choice:
daten.aktualisieren()
message("Daten aktualisiert")

|# Schaltfläche Key 1 (PID)
choice.user.1:
before.choice:
to.key(1)
daten.aktualisieren()

|# Schaltfläche Key 2 (User)
choice.user.2:
before.choice:
to.key(2)
daten.aktualisieren()

|# Schaltfläche Print Prozessliste pro PID
choice.user.3:
before.choice:
ret = run.prog("cmd.exe", "cmd /c r:\apps\baan\bin\bshcmd.exe -p " & str$(tccom990.pid) & " > r:\apps\baan\tmp\bshcmd.txt", RP_WAIT)
if ret = 0 then
| message("Prozessliste in bshcmd.txt ausgegeben")
else
message("Fehler Nr. " & str$(ret) & " beim Erstellen der Prozessliste")
endif

ret = server2client("r:\apps\baan\tmp\bshcmd.txt", "d:\bshcmd.txt",1)
if ret = 0 then
| message("Datei erfolgreich kopiert!")
else
message("Fehler Nr. " & str$(ret) & " beim Kopieren der Datei")
endif

i.file = "d:\bshcmd.txt"
| message(i.file)
ret = app_start(strip$(i.file), "", "", "", "")

|# Schaltfläche KILL PID
choice.user.4:
before.choice:
message("Prozess " & str$(tccom990.pid) & " wird gelöscht!")
ret = run.prog("cmd.exe", "cmd /c r:\apps\baan\bin\bshcmd.exe -e " & str$(tccom990.pid), RP_WAIT)
| message(str$(ret))
if ret = 0 then
message("Prozess wurde gelöscht!")
else
message("Fehler Nr. " & str$(ret) & " beim Löschen")
endif
daten.aktualisieren()

|# Schaltfläche Show Message
choice.user.5:
before.choice:
zoom.to$("tccom9591s000", z.session, "dummy", "", 0)

|# Schaltfläche Key 6 (Sort. Datum)
choice.user.6:
before.choice:
to.key(3)
daten.aktualisieren()

|# Schaltfläche Key 7 (Sort. Company#)
choice.user.7:
before.choice:
to.key(4)
daten.aktualisieren()

|****************************** function section ******************************

functions:

function create.active.userfile()
{
ret = run.prog("cmd.exe", "cmd /c r:\apps\baan\bin\licmon.exe -w > r:\apps\baan\tmp\user.txt", RP_WAIT)
}

function open.userfile()
{
filenamepath = "r:/apps/baan/tmp/user.txt"
file.pointer = seq.open(strip$(filenamepath), "r") | open for reading
if file.pointer < 1 then
mess("tccom90001",1,strip$(filename)) | Datei kann nicht geöffnet werden
choice.again()
endif
}

function delete.working.table()
{
db.retry.point()
select tccom990.*
from tccom990 for update
selectdo
db.delete(ttccom990, db.retry)
endselect
commit.transaction()
}

function fill.working.table()
{
if file.pointer = 0 then
open.userfile()
endif
while ret = 0
ret = seq.gets(stringline, 215, file.pointer)
if ret = 0 then
if stringline(1;6)<>"SERVER" then
separate.string.into.fields()
write.table()
endif
endif
endwhile
}

function separate.string.into.fields()
{
server.i = stringline(1;10)
user.pid = stringline(24;15)
system.i = stringline(39;15)
date.i = stringline(54;10)
time.i = stringline(65;5)
date.time = date.i(7;4) & "-" & date.i(4;2) & "-" & date.i(1;2) & " " & time.i
for i = 2 to 14
if user.pid(i;1)="." then
user.i = user.pid(1;i-1) & " "
user.i = tolower$(user.i) | Umwandeln in Kleinbuchstaben
pid.i = lval(user.pid(i+1;15-i))
endif
endfor

tccom990.pid = pid.i | ProzessID
tccom990.user = user.i | UserID
tccom990.serv = server.i | Servername
tccom990.sysm = system.i | Systemname
tccom990.date = date.time | Datum und Uhrzeit
userstamm.lesen()
}

function write.table()
{
db.retry.point()
select tccom990.*
from tccom990 for update
where tccom990._index1 = {:pid.i}
selectdo
| update set
db.update(ttccom990, db.retry)
selectempty
db.insert(ttccom990, db.retry)
endselect
commit.transaction()
}

function close.userfile()
{
ret = seq.close(file.pointer)
if ret <> 0 then
mess("tccom90002",1,strip$(filename)) | Datei kann nicht geschlossen werden
endif
}

function userstamm.lesen()
{
user.all = user.all + 1
select ttaad200.*
from ttaad200
where ttaad200._index1 = {:user.i}
| where ttaad200.uusr = :user.i
and ttaad200._compnr = 0
selectdo
if ttaad200.comp = 1 then
user.f1 = user.f1 +1
endif
if ttaad200.comp = 2 then
user.f2 = user.f2 +1
endif
if ttaad200.comp = 3 then
user.f3 = user.f3 +1
endif
tccom990.comp = ttaad200.comp
selectempty
message("User " & user.i & " not found in Userstamm!")
tccom990.comp = 0
endselect
}

function daten.aktualisieren()
{
user.f1 = 0
user.f2 = 0
user.f3 = 0
user.all = 0
create.active.userfile()
open.userfile()
delete.working.table()
fill.working.table()
close.userfile()
execute(find.data) | Anzeige aktualisieren
}

evertsen
29th April 2003, 23:03
Is tccom990 a custom table?

Ev

sibon1
30th April 2003, 08:38
Yes, tccom990 is a table i created for reason of being able to use a standard display session.

This is the table definition:

Datum : 30.04.03 [07:18] TABLE DEFINITIONS BY PACKAGE / TABLE / VRC Seite : 1
Standaard_data Firma : 000

------------------------------------------------------------------------------------------------------------------------------------
Package : tc Common BAAN IV Date : 08.10.02
Module : com Common Data BAAN User : jno
Table : tccom990 Aktive User Update Reference Message:
VRC : B40Cc4wuh1 Common BAAN IVc4 Delete Reference Message:
Relation Type : All fields
------------------------------------------------------------------------------------------------------------------------------------
Field Name | Bezeichnung | Domain | Datatype Physic.| Mand. | Acti | Refer. Reference
| | | length | | | Table Mode
---------------+-------------------------------------+-----------------+---------------------+-------+-------+----------------------
1 pid | ProzessID | tcmcs.long | Long 4 | Nein | Ja |
2 user | UserID | tcmcs.str8 | String 8 | Nein | Ja |
3 serv | Server | tcmcs.str10 | String 10 | Nein | Ja |
4 sysm | System | tcmcs.str15 | String 15 | Nein | Ja |
5 date | Datum/Uhrzeit | tcmcs.str16 | String 16 | Nein | Ja |
6 comp | Company | tccomp | Integer 2 | Nein | Ja |
-----
Record Length: 55

------------------------------------------------------------------------------------------------------------------------------------
Index | Bezeichnung | Index Parts | Dupl | Acti
| | 1 2 3 4 5 | |
-------+--------------------------------------------------------------+----------------------------------------------+-------+------
1 | ProzessID | pid | Nein | Ja
2 | UserID+ProzessID | user pid | Ja | Ja
3 | Datum+Uhrzeit | date pid | Nein | Ja
4 | Companynr.+User | comp user pid | Nein | Ja
------------------------------------------------------------------------------------------------------------------------------------

mark_h
30th April 2003, 16:56
Josef,

Do you think you could post the source and maybe a snapshot of the form for tccom9591s000?

Thanks

Mark

AWondergem
1st May 2003, 11:19
Anyone tried this for Unix?
Any documentation on bshcmd

sibon1
2nd May 2003, 09:08
This is the code from subsession tccom9591s000:

Sending message to 1 user is OK, but the function sending the message to all user - this does not work!! I did not yet find the time to correct this.

|******************************************************************************
|* tccom9591 0 VRC B40C c4 wuh1
|* *Aktive User Message senden
|* Nobis Josef
|* 2002-12-13
|******************************************************************************
|* Main table tccom990 Aktive User, Form Type 1
|******************************************************************************
|******************************************************************************
|* All Rights Reserved
|*
|* Permission to use, copy, modify, and distribute this software and its
|* documentation for any purpose and without fee is hereby granted,
|* provided that the above copyright notice appear in all copies and that
|* both that copyright notice and this permission notice appear in
|* supporting documentation.
|*
|* Josef N. and Baanboard.com DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|* AND FITNESS, IN NO EVENT SHALL Josef Nobis nor Baanboard.com BE LIABLE FOR ANY
|* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|* OR PERFORMANCE OF THIS SOFTWARE.
|******************************************************************************

|****************************** declaration section ***************************
declaration:

table ttccom990 | Aktive User

extern long ret
extern long file.pointer
extern long i
extern long fieldcounter
extern long item.exist
extern long rec.good
extern long rec.bad
extern domain tcmcs.str50 tempstr

extern domain tcitem item.i
extern domain tcqsl1 quan.i

extern domain tcmcs.str10 server.i
extern domain tcmcs.str15 user.pid
extern domain tcmcs.str12 user.i
extern domain tcmcs.long pid.i
extern domain tcmcs.str15 system.i
extern domain tcmcs.str10 date.i
extern domain tcmcs.str5 time.i
extern domain tcmcs.str16 date.time
extern domain tcqiv1 user.f1
extern domain tcqiv1 user.f2
extern domain tcqiv1 user.f3
extern domain tcqiv1 user.all

extern domain tcmcs.str50 i.file
extern domain tcmcs.str50 baan.message
extern domain tcmcs.str50 baan1.message
extern domain tcmcs.str1 qm | Quotation Mark = "


|****************************** form section **********************************

|# Schaltfläche Show Message an 1 user
choice.user.0:
before.choice:
send.message.to.user()
if ret = 0 then
message("Message ausgegeben")
else
message("Fehler Nr. " & str$(ret) & " beim Message senden")
endif

|# Schaltfläche Show Message an all user
choice.user.1:
before.choice:
select tccom990.*
from tccom990
selectdo
send.message.to.user()
endselect
if ret = 0 then
message("Message an Alle ausgegeben")
else
message("Fehler Nr. " & str$(ret) & " beim Message senden")
endif

functions:

function send.message.to.user()
{
qm = chr$(34) | Quotation Mark = "
baan1.message = qm & baan.message & qm & " " | incl. Hochkomma
ret = run.prog("cmd.exe", "cmd /c r:\apps\baan\bin\bshcmd.exe -M " & baan1.message & str$(tccom990.pid), RP_WAIT)
}

pedromrs
2nd May 2003, 11:06
Hi all,

Some great code Josef.
I did a little change to the process listing. I used some code I had from a batch file that I runned for administration:


|******************************************************************************
|* tcmcg0902 0 VRC B40C c4 expl
|* Consultar Tabela de Subprocessos
|* Pedro Sousa
|* 2003-04-30
|******************************************************************************
|* Main table tcmcg901 Tabela de Subprocessos, Form Type 2
|*
|*
|* Portions of original code by Nobis Josef 2002-10-8 - BaanBoard.com
|*
|*
|* Permission to use, copy, modify, and distribute this software and its
|* documentation for any purpose and without fee is hereby granted,
|* provided that the above copyright notice appear in all copies and that
|* both that copyright notice and this permission notice appear in
|* supporting documentation.
|*
|* Josef N. and Baanboard.com DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|* AND FITNESS, IN NO EVENT SHALL Norbert Wimmer nor Baanboard.com BE LIABLE FOR ANY
|* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|* OR PERFORMANCE OF THIS SOFTWARE.
|******************************************************************************

|******************************************************************************

|****************************** declaration section ***************************
declaration:

table ttcmcg901 | Tabela de Subprocessos
extern domain tcmcs.long procid
extern domain tcmcs.str20 user
string baandir(20),baandir1(20)
long ret
extern domain tcmcs.str215 stringline
extern domain tcmcs.str215 last.stringline
extern long ret
extern long file.pointer.proc
extern domain tcmcs.str30 filename
extern domain tcmcs.str50 filenamepath
extern domain tcmcs.long pid.i

|****************************** form section **********************************
form.1:
init.form:
import("tcmcg900.pid",procid)
import("tcmcg900.user",user)
baandir1="e:/baan"
baandir="e:\baan"
ret = run.prog("cmd.exe", "cmd /c "&baandir&"\bin\bshcmd.exe -p " & str$(procid) & " > "&baandir&"\tmp\proc.txt", RP_WAIT)
if ret <> 0 then
message("Ocorreu um erro ao listar os processos.")
exit()
else
delete.process.table()
open.procfile()
fill.proc.working.table()
close.procfile()
endif

choice.user.0:
before.choice:
ret = run.prog("cmd.exe", "cmd /c "&baandir&"\bin\bshcmd.exe -p " & str$(procid) & " > "&baandir&"\tmp\proc.txt", RP_WAIT)
if ret <> 0 then
message("Ocorreu um erro ao listar os processos.")
exit()
else
delete.process.table()
open.procfile()
fill.proc.working.table()
close.procfile()
execute(first.set)
endif

choice.user.1:
before.choice:
ret = run.prog("cmd.exe", "cmd /c "&baandir&"\bin\bshcmd.exe -k " & str$(tcmcg901.pid)& " " & str$(procid) & " > "&baandir&"\tmp\prockill.txt", RP_WAIT)
if ret <> 0 then
message("Ocorreu um erro ao terminar o processo.")
else
message("Processo terminado com sucesso.")
endif

ret = run.prog("cmd.exe", "cmd /c "&baandir&"\bin\bshcmd.exe -p " & str$(procid) & " > "&baandir&"\tmp\proc.txt", RP_WAIT)
if ret <> 0 then
message("Ocorreu um erro ao listar os processos.")
exit()
else
delete.process.table()
open.procfile()
fill.proc.working.table()
close.procfile()
execute(first.set)
endif

functions:

function open.procfile()
{
filenamepath = baandir1&"/tmp/proc.txt"
file.pointer.proc = seq.open(strip$(filenamepath), "r") | open for reading
if file.pointer.proc < 1 then
message("Não foi possível abrir o ficheiro de processos")
exit()
endif
}

function delete.process.table()
{
db.retry.point()
select tcmcg901.*
from tcmcg901 for update
selectdo
db.delete(ttcmcg901, db.retry)
endselect
commit.transaction()
}

|Quando a linha começa por object a anterior é de processos
function fill.proc.working.table()
{
if file.pointer.proc = 0 then
open.procfile()
endif
while ret = 0
ret = seq.gets(stringline, 215, file.pointer.proc)
if ret = 0 then
if stringline(1;7)="object:" then
separate.proc.string.into.fields()
write.proc.table()
endif
last.stringline=stringline
endif
endwhile
}

function separate.proc.string.into.fields()
{
tcmcg901.pid = lval(shiftl$(last.stringline(1;7)))
pid.i=tcmcg901.pid
tcmcg901.session = shiftl$(strip$(last.stringline(22;13)))
tcmcg901.ticks = shiftl$(strip$(last.stringline(36;10)))
}

function write.proc.table()
{
db.retry.point()
select tcmcg901.*
from tcmcg901 for update
where tcmcg901._index1 = {:pid.i}
selectdo
| update set
db.update(ttcmcg901, db.retry)
selectempty
db.insert(ttcmcg901, db.retry)
endselect
commit.transaction()
}

function close.procfile()
{
ret = seq.close(file.pointer.proc)
if ret <> 0 then
message("Não foi possível fechar o ficheiro de processadores")
endif
}


If you use Josef's code the import variables should be changed to the appropriate table.

Table definition:
------------------------------------------------------------------------------------------------------------------------------------
Pacote : tc Common BAAN IV Data : 30/04/03
Módulo : mcg Desenv. feitos na MCG Utilizador BAAN : psousa
Tabela : tcmcg901 Tabela de Subprocessos Actualizar mensagem ref.:
VRC : B40Cc4expl Elimnr mensag. referênc.:
Tipo de relação : Todos campos
------------------------------------------------------------------------------------------------------------------------------------
Nome de campo | Descrição | Domínio | T. dados Tamanho| Obrg. | Actv. | Tabela Modo
| | | físico | | | referê. referência
---------------+-------------------------------------+-----------------+---------------------+-------+-------+----------------------
1 pid | | tcmcs.long | Long 4 | Não | Sim |
2 session | Sessão | tcmcs.str15 | String (al 15 | Não | Sim |
3 ticks | Ticks | tcmcs.str15 | String (al 15 | Não | Sim |
-----
Tamanho registo: 34

------------------------------------------------------------------------------------------------------------------------------------
Índice | Descrição | Partes índice | Dupl. | Actv.
| | 1 2 3 4 5 | |
-------+--------------------------------------------------------------+----------------------------------------------+-------+------
1 | PID | pid | Não | Sim
2 | PID+Session | pid session | Sim | Sim
------------------------------------------------------------------------------------------------------------------------------------

I turned the main session into an exclusive mode session to avoid trouble with this tables.

form.1:
init.form:
appl.set("tdmcg0900m000", APPL.WRITE + APPL.WIDE )

if appl.set("tdmcg0900", APPL.EXCL) > 0 then
message("Esta sessão está a ser usada por outro utilizador.")
exit()
endif

after.program:
appl.delete("tdmcg0900m000")


To call the subsession in the main session:

zoom.to$("tcmcg0902s000", z.session, "dummy", "", 0)


Sorry the session is in portuguese. Choice.0 is used to refresh and choice.1 to kill individual user processes.

I could not attach an image. If a moderator could make the favor of removing the link and attach the linked image I would greatly appreciate (bandwidth). Thanks ;)

patvdv
2nd May 2003, 11:40
There's no way to add an image afterwards to a post so here it is in a separate post :)

pedromrs
2nd May 2003, 11:59
Thanks Patrick...

dbinderbr
10th June 2003, 22:20
I have tried to run BSHCMD from de command line but I am getting an error message. Maybe you have already seen it before.

I tried to use, for example, bshcmd -p 4248.
The message I got:
- bshcmd: OpenWindowsStation for BaanWinstation failed (error 2)

Ideas are welcome.

dbinderbr
10th June 2003, 22:24
In addition... I got the same message using any other option besides the -p.

ahulikavi
10th November 2003, 13:13
Hi Josef,

Extremely useful code, thanks. I have a few problems though,When I try to use command bshcmd6.1 -p to generate process list as done by you, no output is generated. Any ideas ?

I am on solaris2.6 Port 6.1c.06.07

One more observation Kill option will work only with with user root.

regards,

sibon1
11th November 2003, 09:29
Hi,

this code works on server running a windows OS!

Please search in this forum for bshcmd on unix OS.
Jo

nanuco
17th November 2003, 13:28
Does this session and code work in BAAN V.

Thanks for your reply.

jdboer
17th November 2003, 15:00
We used the code to create such a session. This works very good! Thanks for the ideas and documentation!

One things that's nice to have with this session is:
Is it also possible to build something in the session to see the idle time for each user?

Maybe some BaaN gurus have idea's if this is possible and/or some (code/command) hints.

ghk1995
17th June 2004, 05:56
Hi Josef,

I created the subsession to enter the messages
I entered one field baan.message into the form.

When I open the session, the cursor do not appear on that field.
I have to click on that field before I can start entering the message.
What is the command to use to ensure the cursor appear on the
field when I first enter that session. I tried using input() and set.focus()
but does not seem to work.

Thanks and regards

sibon1
18th June 2004, 11:01
have you tried 'field order' in maintain forms?

in field order you can set the order of the fields...
Jo

rksundhar_2000
29th June 2004, 11:05
Could you plz make a patch of this project and attach ?

~Vamsi
6th July 2004, 20:22
Sundhar,

The code is posted so you should be able to generate the requisite sessions fairly easily.

We try to avoid posting patches because

different versions of Baan require different patches
when you compile a program you have a chance to read it and understand what is going under the hood.
you realize that programs that run on a Baan server are not like the ones you run on your pc. They impact the entire organization. So you get to make the decision whether or not to compile and run the program.

Having said all that, we are open to having dumps if someone takes on the responsibility to create and support them. After all this is a collective effort.