Finbom
(Fresh Scripter)
2005-09-19 11:16 AM
Rightclick and work with several files.

Hi!

I am working on a script that lets the user select one or several files in the windows explorer, rightclick and select "send to Archive".
When they select this a kix-script moves the files to a selected destination.. this works fine but the script runs one time for each file.

Does anyone know how I can make the script understand that more than one file is selected and only run the scrpt once?
Hope you understand what I mean.

Regards, Magnus Finbom


LonkeroAdministrator
(KiX Master Guru)
2005-09-19 11:32 AM
Re: Rightclick and work with several files.

well...
I think explorer itself sends the fileaction command to each file, so you can't directly fix it.
but you could make your script have a wait a second thing.

like, the first file gets to the script, it writes it to temp ini file.
then, it waits a sec or so waiting if more files appear.
the other files are also triggered similarly so they also add to the ini.
if they see the other process running, they quit there.

this leaves only 1 process that processes all of the files.


Finbom
(Fresh Scripter)
2005-09-19 03:42 PM
Re: Rightclick and work with several files.

hmmm. can be tricky.
To make it more difficult.
Before the archiving, the user is asked for a archive-number , this is the name for the folder that the files are sent to.
And I dont want the user to be needing to type the number for each file.

regards, magnus finbom


Richard H.Administrator
(KiX Supporter)
2005-09-19 03:48 PM
Re: Rightclick and work with several files.

It's not so tricky.

The first one to start updates the list of files to be actioned, sets a flag in registry or ini file to say it is busy, and then prompts the user.

The next one to starts checks the registry, sees that there is already a user prompt open so just adds the file name to the list of files to be actioned and exits.

When the user responds to the prompt the first process gets the list of all the files to action and deals with them.


Les
(KiX Master)
2005-09-19 04:46 PM
Re: Rightclick and work with several files.

The problem with INI files, cookies or reg contents is that they can become out of sync with the process. If the process terminates, it may leave the flag incorrectly toggled.

A more rugged approach is to hold a lock on a file. If the locking program is terminated, the lock will clear.


Richard H.Administrator
(KiX Supporter)
2005-09-19 04:58 PM
Re: Rightclick and work with several files.

To make it completely bullet proof you'll need two semaphores. One to identify the "master" process and one to control access to the shared communication, whether it be ini file, registry or whatever.

LonkeroAdministrator
(KiX Master Guru)
2005-09-19 05:24 PM
Re: Rightclick and work with several files.

lock a file...
that might be little not so simple as it sounds.
the flag having the process ID and start ticks should be enough proof.


Richard H.Administrator
(KiX Supporter)
2005-09-19 05:39 PM
Re: Rightclick and work with several files.

What flag?

You need an atomic set-and-check process, and without access to latches/semaphores the "open a file in exclusive read mode" it about as close as you are going to get.


LonkeroAdministrator
(KiX Master Guru)
2005-09-19 05:41 PM
Re: Rightclick and work with several files.

flag like:
Code:

$=writeprofilestring("myIni.ini","section","father",@pid+" "+@ticks)



Richard H.Administrator
(KiX Supporter)
2005-09-19 05:50 PM
Re: Rightclick and work with several files.

What if two processes write to it at (nearly) the same time?

What if a process abends, leaving itself set as master?


LonkeroAdministrator
(KiX Master Guru)
2005-09-19 10:06 PM
Re: Rightclick and work with several files.

well, the nearly same time write is a concern to think about but still...
not sure if it can happen at all in real life.


Richard H.Administrator
(KiX Supporter)
2005-09-20 10:37 AM
Re: Rightclick and work with several files.

Well, imagine:
  1. Process A checks the file and there is no master.
  2. Process B checks the file and there is no master.
  3. Process A writes a key to say that it is a master.
  4. Process A checks the key to ensure that it is still master.
  5. Process B writes a key to say that it is a master.
  6. Process B checks the key to ensure that it is still master


Now, both processes think that they are masters.

You could introduce a sleep after writing the key. In this case Process A would see that process B had overwritten the master key so it would demote itself to a slave. In most cases this would probably work. This technique fails when the master process dies without completing it's task. To guard against this you would need all the slave processes to monitor the master and go through the master election process if the master dies.

Using a lock file makes the whole thing much more simple.

The example here will allows one arbitrary process to become the master. Only one process can become a master because of the atomic nature of locking a file in write mode.

If the master process it killed off then a slave will automatically promote itself to master status and complete the work. Slaves will only exit when their file has been serviced which means that as long as there is at least one slave left the job will be completed.

For this example I have not added code to lock the INI file while writing - I've no reason to believe it is necessary for local INI files.

SingleStream.kix
Code:
Break ON
$=SetOption("Explicit","ON")

; NB Pass the parameter on the command line as "$sFILE"

Dim $iIsMaster
Dim $sIni,$sLatch,$sInput,$sUnique,$sFileSection

$sLatch=".\LatchFile.TXT"
$sIni=".\IPC.INI"
$sFileSection="FILELIST"

; Generate a unique key for IPC comms
$sUnique=CSTR(@PID)+"."+@DATE+"."+@TIME+"."+@MSECS+"."+@TICKS

If Not IsDefined($sFile)
"No parameter $$sFile passed on command line - aborting"+@CRLF
Exit 1
EndIf

; Write parameter to IPC
$=WriteProfileString($sIni,$sFileSection,$sUnique,$sFile)

; We will either become the master process, or we will wait for the master process to action our file
While ReadProfileString($sIni,$sFileSection,$sUnique)<>"" And Not $iIsMaster
If Not $iIsMaster
$iIsMaster=FreeFileHandle()
If Open($iIsMaster,$sLatch,1+4)
$iIsMaster=0
Sleep 0.1 ; Give the CPU a break!
Else
; Check again to avoid race conditions
If ReadProfileString($sIni,$sFileSection,$sUnique)<>""
"Process "+@PID+" has become the master, enter a string to continue: " GetS $sInput
Else
$=Close($iIsMaster)
$iIsMaster=0
EndIf
EndIf
EndIf
Loop

; If we are the master process then we need to action the file list, otherwise our job is done.
If $iIsMaster
For Each $sUnique in Split(ReadProfileString($sIni,$sFileSection,""),Chr(10))
If $sUnique
$sFile=ReadProfileString($sIni,$sFileSection,$sUnique)
"Slave process # "+Split($sUnique,".")[0]+" has asked master to deal with '"+$sFile+"'"+@CRLF
;
; ***************************
; * Do file processing here *
; ***************************
;
; Delete file key to release slave
$=WriteProfileString($sIni,$sFileSection,$sUnique,"")
EndIf
Next
"Hit return to exit: " GetS $
Else
"Slave process "+@PID+" released."+@CRLF
EndIf

; vim: ts=4 sw=4 fdc=4 fdm=marker ai



Test batch file:

SingleStreamTest.bat
Code:

Start "Single stream test file ONE" kix32.exe SingleStream.kix $sFile="This is file one"
Start "Single stream test file TWO" kix32.exe SingleStream.kix $sFile="This is file two"
Start "Single stream test file THREE" kix32.exe SingleStream.kix $sFile="This is file three"
Start "Single stream test file FOUR" kix32.exe SingleStream.kix $sFile="This is file four"



Finbom
(Fresh Scripter)
2005-09-22 03:04 PM
Re: Rightclick and work with several files.

A breakthrough.. or at least a workaround.

I found out that if I skip the right-click option and use the right-click "SendTo"-feature it works better.
I have an shortcut for a very simple cmd-file that simply echoes all selected files to an text-file.

Now I wonder two things.
1.How do I get the variables from the commandline into the kix-script.
2.How do I make the script to know how many files selected?

A progress. :-)

regards, Magnus Finbom