Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks.

Go Back   Vista Forums > Misc Newsgroups > PowerShell

Vista - Open file for exclusive access

Reply
 
Old 05-15-2007   #11 (permalink)
char1iecha1k


 
 

Re: Open file for exclusive access

On 15 May, 20:32, "Keith Hill [MVP]"
<r_keith_h...@no.spam.thank.u.hotmail.com> wrote:
> If you use the FileShare parameter then the file will be locked to anyone
> else until the file is closed (by disposing of the FileStream). The
> Lock/Unlock methods allow you lock/unlock certain regions of a file where
> that file allows write access to others.
>
> --
> Keith
>
> "Joris van Lier" <whiz...@hotmail.com> wrote in messagenews:etPbqbwlHHA.4188@TK2MSFTNGP02.phx.gbl...
>
>
>
> Keith Hill wrote:
> > "char1iecha1k" <charlesgarg...@gmail.com> wrote in message
> >news:1179176871.496647.42740@l77g2000hsb.googlegroups.com...
> >> Hi,

>
> >> I would like to open a file for exclusive access for the duration of
> >> a script. If the script fails or finishes the lock must be released.
> >> This is to prevent another user or process from accessing the same
> >> data file. I have googled to no avail.

>
> >> Thanks in advance

>
> > Perhaps you should try this FileStream constructor:

>
> > public FileStream (
> > string path,
> > FileMode mode,
> > FileAccess access,
> > FileShare share
> > )

>
> > And set the share parameter to FileShare.None.

>
> Good suggestion,
>
> Is the FileShare.None option enough to lock the file or should one call
> $fileStream.Lock(0,$filestream.Length-1)?
>
> And how about unlocking the file, will dereferencing the FileStream lift the
> lock, or is an explicit call to unlock required/recommended?
>
> --
> Joris van Lier
> Please note that all scripts and opinions are supplied "as is" and with
> no warranty Blog:http://whizzrd.spaces.live.com


OK tried this



My System SpecsSystem Spec
Old 05-15-2007   #12 (permalink)
char1iecha1k


 
 

Re: Open file for exclusive access

On 15 May, 20:32, "Keith Hill [MVP]"
<r_keith_h...@no.spam.thank.u.hotmail.com> wrote:
> If you use the FileShare parameter then the file will be locked to anyone
> else until the file is closed (by disposing of the FileStream). The
> Lock/Unlock methods allow you lock/unlock certain regions of a file where
> that file allows write access to others.
>
> --
> Keith
>
> "Joris van Lier" <whiz...@hotmail.com> wrote in messagenews:etPbqbwlHHA.4188@TK2MSFTNGP02.phx.gbl...
>
>
>
> Keith Hill wrote:
> > "char1iecha1k" <charlesgarg...@gmail.com> wrote in message
> >news:1179176871.496647.42740@l77g2000hsb.googlegroups.com...
> >> Hi,

>
> >> I would like to open a file for exclusive access for the duration of
> >> a script. If the script fails or finishes the lock must be released.
> >> This is to prevent another user or process from accessing the same
> >> data file. I have googled to no avail.

>
> >> Thanks in advance

>
> > Perhaps you should try this FileStream constructor:

>
> > public FileStream (
> > string path,
> > FileMode mode,
> > FileAccess access,
> > FileShare share
> > )

>
> > And set the share parameter to FileShare.None.

>
> Good suggestion,
>
> Is the FileShare.None option enough to lock the file or should one call
> $fileStream.Lock(0,$filestream.Length-1)?
>
> And how about unlocking the file, will dereferencing the FileStream lift the
> lock, or is an explicit call to unlock required/recommended?
>
> --
> Joris van Lier
> Please note that all scripts and opinions are supplied "as is" and with
> no warranty Blog:http://whizzrd.spaces.live.com


ok this is what i get, it still randomly (as far as i can tell) fails

1# gc test.ps1
&{
trap { write-host "error"; exit }
$script:test = new-object System.IO.FileStream("cmdc.lck",
[System.IO.FileMode]::Open, [System.IO.FileAccess]::Read,
[system.Io.FileShare]::None)
}
write-host "success"
2# .\test.ps1
success
3# .\test.ps1
error
4# .\test.ps1
success
5# .\test.ps1
success
6# .\test.ps1
error
7# .\test.ps1
error


My System SpecsSystem Spec
Old 05-15-2007   #13 (permalink)
Keith Hill [MVP]


 
 

Re: Open file for exclusive access

"char1iecha1k" <charlesgargent@gmail.com> wrote in message
news:1179266035.977797.5470@h2g2000hsg.googlegroups.com...
>
> ok this is what i get, it still randomly (as far as i can tell) fails
>
> 1# gc test.ps1
> &{
> trap { write-host "error"; exit }
> $script:test = new-object System.IO.FileStream("cmdc.lck",
> [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read,
> [system.Io.FileShare]::None)
> }
> write-host "success"
> 2# .\test.ps1
> success
> 3# .\test.ps1
> error
> 4# .\test.ps1
> success
> 5# .\test.ps1
> success
> 6# .\test.ps1
> error
> 7# .\test.ps1
> error


I think the "non-determinism" you are seeing are the resulting of the
garbage collector sporadically closing the "for you". If you want to avoid
this, then you should explicitly close the file when you are done with it.
I would modify the test like so:

&{
trap { write-host "error"; exit }
$script:test = new-object System.IO.FileStream("cmdc.lck",
[System.IO.FileMode]::Open, [System.IO.FileAccess]::Read,
[system.Io.FileShare]::None)
Start-Sleep -seconds 30
$script:test.dispose()
}

Now run your test in one PowerShell and then try to run the same script from
another console. The separate console should consistenly fail until the
first script execution times out and closes the file.

--
Keith


My System SpecsSystem Spec
Old 05-16-2007   #14 (permalink)
Keith Hill


 
 

Re: Open file for exclusive access

"Keith Hill [MVP]" <r_keith_hill@no.spam.thank.u.hotmail.com> wrote in
message news:%23j4$yL0lHHA.4684@TK2MSFTNGP03.phx.gbl...
> I think the "non-determinism" you are seeing are the resulting of the
> garbage collector sporadically closing the "for you".


Doh! That should read:

I think the "non-determinism" you are seeing is the result of the
garbage collector sporadically collecting and closing the file "for you".

Since you don't close the file explicitly the file won't get closed until
the GC notices that the FileStream object that you created during the
previous script execution is no longer needed and finalizes it (which closes
the underlying file hanlde).

--
Keith

My System SpecsSystem Spec
Old 05-18-2007   #15 (permalink)
char1iecha1k


 
 

Re: Open file for exclusive access

On May 16, 5:15 am, "Keith Hill" <r_keith_h...@mailhot.nospamIdotcom>
wrote:
> "Keith Hill [MVP]" <r_keith_h...@no.spam.thank.u.hotmail.com> wrote in
> messagenews:%23j4$yL0lHHA.4684@TK2MSFTNGP03.phx.gbl...
>
> > I think the "non-determinism" you are seeing are the resulting of the
> > garbage collector sporadically closing the "for you".

>
> Doh! That should read:
>
> I think the "non-determinism" you are seeing is the result of the
> garbage collector sporadically collecting and closing the file "for you".
>
> Since you don't close the file explicitly the file won't get closed until
> the GC notices that the FileStream object that you created during the
> previous script execution is no longer needed and finalizes it (which closes
> the underlying file hanlde).
>
> --
> Keith


When the script runs it sometimes reports a locked file and sometimes
it doesnt, this is probably the "garbage collector" as you say,
however whilst that shell is still open the file remains locked to
other process. the only way to clear the lock is to end the shell.

an alternate method would be to use an trap handler to close the
stream on a file already open error. something like below. Does anyone
know what type of an exception this error is?
"
New-Object : Exception calling ".ctor" with "4" argument(s): "The
process cannot access the file 'C:\test.lck' because it is being used
by another process."
At C:\test.ps1:15 char:26
+ $script:test = new-object <<<< System.IO.FileStream("test.lck",
[System.IO.FileMode]::Open, [System.IO.FileAccess]::
Read, [system.Io.FileShare]::None)
"

then I could do something like this (i dont know wht the exception
type is?)

Trap [Exceptiontype] { Write-Host "file in use" -foregroundcolor red;
$Script:lck.close(); Exit }
$Script:lck = New-Object System.IO.FileStream("test.lck",
[System.IO.FileMode]::Open, [System.IO.FileAccess]::Read,
[system.Io.FileShare]::None)

then if the script errors before it finishes the trap handler will
close the stream

My System SpecsSystem Spec
Old 05-18-2007   #16 (permalink)
Keith Hill


 
 

Re: Open file for exclusive access

"char1iecha1k" <charlesgargent@gmail.com> wrote in message news:1179496322.852249.78370@q23g2000hsg.googlegroups.com...
> When the script runs it sometimes reports a locked file and sometimes
> it doesnt, this is probably the "garbage collector" as you say,
> however whilst that shell is still open the file remains locked to
> other process. the only way to clear the lock is to end the shell.
>

....
> an alternate method would be to use an trap handler to close the
> stream on a file already open error. something like below. Does anyone
> know what type of an exception this error is?
> "
> then I could do something like this (i dont know wht the exception
> type is?)


You don't have to specify an exception type, you could just trap all errors.

>
> Trap [Exceptiontype] { Write-Host "file in use" -foregroundcolor red;
> $Script:lck.close(); Exit }
> $Script:lck = New-Object System.IO.FileStream("test.lck",
> [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read,
> [system.Io.FileShare]::None)
>
> then if the script errors before it finishes the trap handler will
> close the stream


Try this variant and see what you think:

param([switch]$Wait)

function Cleanup {
if ($script:test) {
$script:test.dispose()
$script:test = $null
}
}

trap { write-host "Error: $_"; Cleanup; exit }

$fileOpenArgs = "cmdc.lck", [IO.FileMode]::OpenOrCreate, [IO.FileAccess]::Read, [IO.FileShare]::None

if ($Wait) {
$secs = 10
do {
trap {
write-warning "Lock file in use. Waiting $secs seconds"
write-debug "$_"
start-sleep $secs
continue
}

$script:test = new-object System.IO.FileStream $fileOpenArgs
}
until ($script:test)
}
else {
$script:test = new-object System.IO.FileStream $fileOpenArgs
}

"Acquired lock, sleeping 30 seconds"
Start-Sleep 30
"Done"

Cleanup


BTW since we have full access to the .NET Framework you are not limited to using files for locks. You could also use a System.Threading.Mutex for inter-process locking. I'm not saying you should - just pointing out that the option exists.

--
Keith
My System SpecsSystem Spec
Reply

Thread Tools


Similar Threads
Thread Forum
Solved Error "Could Not Open The File: Access Denied" setting up print to file General Discussion
can't open access control editor. Access is denied General Discussion
XDocument Exclusive Access .NET General
in vb.net how to open a file from file download prompt without askinguser to save it or run it....just open it in internet explorer .NET General
How to open a file for read/write access in Program Files directory Vista security


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46