• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

[Reflection.Assembly]::LoadFile locks file

N

npoto

#1
I am learning how to use custom dll with Powershell. I found that when I
load the file with [Reflection.Assembly]::LoadFile, the file is locked. I
cannot rebuild or replace the DLL until I exit Powershell.

I search the Web and found some references to the use of shadow copy to
avoid this issue. But I am new to .Net and don't know how to do this.

Please show some examples how to do this within Powershell.

My Powershell script is
[Reflection.Assembly]::LoadFile("C:\Documents and Settings\k315.MIHDQ\My
Documents\Visual Studio
2005\Projects\KClassLibraries\ClassLibrary1\bin\Debug\classlibrary1.dll")

$class1 = new-object Classlibrary1.Class1

$class1

thanks,
ktmd
 

My Computer

A

Adam Milazzo

#2
npoto wrote:
> I am learning how to use custom dll with Powershell. I found that when I
> load the file with [Reflection.Assembly]::LoadFile, the file is locked. I
> cannot rebuild or replace the DLL until I exit Powershell.
>
> I search the Web and found some references to the use of shadow copy to
> avoid this issue. But I am new to .Net and don't know how to do this.
>
> Please show some examples how to do this within Powershell.
>
> My Powershell script is
> [Reflection.Assembly]::LoadFile("C:\Documents and Settings\k315.MIHDQ\My
> Documents\Visual Studio
> 2005\Projects\KClassLibraries\ClassLibrary1\bin\Debug\classlibrary1.dll")
>
> $class1 = new-object Classlibrary1.Class1
>
> $class1
>
> thanks,
> ktmd


Basically, copy the file into a temporary location and load that one.
Then, you can replace the original file.
 

My Computer

K

klumsy@gmail.com

#3
yep there is not much you can do, because unlike standard windows where
you can loadlibrary (load a dll dynamically) and freelibirary.. you
can't free an assembly that is loaded, without killing the whole
process.. HOWEVER if you create a new app domain and load it into that
app domain, then you can free the whole app domain and that works.. i
have done that a little bit in the past..

the problem with copying it to a temporary file, is if you are wanting
to load it again more than once.. you going to have to the same
problem, next time its not going to be able to copy to your temp file,
and besides even if you renamed the file random or something, you
already have that assembly loaded into memory.. i'm not sure how dotnet
will handle 2 idenitcal assemblies loaded..
 

My Computer

A

Adam Milazzo

#4
klumsy@gmail.com wrote:
> yep there is not much you can do, because unlike standard windows where
> you can loadlibrary (load a dll dynamically) and freelibirary.. you
> can't free an assembly that is loaded, without killing the whole
> process.. HOWEVER if you create a new app domain and load it into that
> app domain, then you can free the whole app domain and that works.. i
> have done that a little bit in the past..
>
> the problem with copying it to a temporary file, is if you are wanting
> to load it again more than once.. you going to have to the same
> problem, next time its not going to be able to copy to your temp file,
> and besides even if you renamed the file random or something, you
> already have that assembly loaded into memory.. i'm not sure how dotnet
> will handle 2 idenitcal assemblies loaded..


If you want to load the file multiple times you can try these...

1. Maintain a reference to the assembly file returned from LoadFile(),
and use that assembly reference to lookup and instantiate types. (using
Assembly.GetType)

2. If that doesn't work, you'd have to load it into a separate AppDomain
and free the AppDomain before reloading, but then that makes using it
complicated because you can only use types that can be marshalled across
AppDomains...
 

My Computer

K

klumsy@xtra.co.nz

#5
a common thing i do in powershell analyer for this, if i don't want to
have to reload, and if i am just testing something configuration is a
call another instance of powershell.. i.e something like this

#region test code in another powershell.exe instance

powershell {

assembly.load sort of thing..
$myclass = new-object whatever sort of thing.
$myclass.dotest();
and whatever else

}

#end region

then as its being run in another process that process ends and you
don't have any more problems.. the cool thing about this is the data
gets marshelled back to the main host (and is still dotnet objects,
however empty proproty bags (i.e if you did powershell { gps } , rather
than having life system.diagnostic.process objects in the property
grid, you'd get ones with the same properties, but they won't have any
methods, and they have gone through teh same process as export-clixml,
import-clixml

however the disadvantage of this is you can dynamically just decied to
run differnet test and code on the same instance.. and you run the
powershell.exe, load the assembly, run the test code all at once.. so
it all depends on the use..

if i'm building a snapin, or a C# assembly that i want to test in
powershell, what i typically do is inside visual studio, set the run
target as powershellanalyer.exe mytestscript.ps1
so that when you click run in vs.net it autoloads powershell analyzer
and automatically loads a file.. in that file i have a region that i
use to load the assembly dynamically, then other regions for various
tests, so its as easy and highlighting some collapsed regions of code
and pressing f5, and also typing adhoc expression you want to run
against it.. another cool thing about this technique, is you can put
breakpoints in the C# code you are testing..

Karl
 

My Computer

N

npoto

#6
Thanks for the answers.
Luckily I am not writing long running PS scripts. So this lock issue is not
a big deal for me. It is inconvenient during coding/testing.

I hope someone would post a sample PS script showing how to use AppDomain.
I am still learning .net so this is still over my head.



"klumsy@xtra.co.nz" wrote:

> a common thing i do in powershell analyer for this, if i don't want to
> have to reload, and if i am just testing something configuration is a
> call another instance of powershell.. i.e something like this
>
> #region test code in another powershell.exe instance
>
> powershell {
>
> assembly.load sort of thing..
> $myclass = new-object whatever sort of thing.
> $myclass.dotest();
> and whatever else
>
> }
>
> #end region
>
> then as its being run in another process that process ends and you
> don't have any more problems.. the cool thing about this is the data
> gets marshelled back to the main host (and is still dotnet objects,
> however empty proproty bags (i.e if you did powershell { gps } , rather
> than having life system.diagnostic.process objects in the property
> grid, you'd get ones with the same properties, but they won't have any
> methods, and they have gone through teh same process as export-clixml,
> import-clixml
>
> however the disadvantage of this is you can dynamically just decied to
> run differnet test and code on the same instance.. and you run the
> powershell.exe, load the assembly, run the test code all at once.. so
> it all depends on the use..
>
> if i'm building a snapin, or a C# assembly that i want to test in
> powershell, what i typically do is inside visual studio, set the run
> target as powershellanalyer.exe mytestscript.ps1
> so that when you click run in vs.net it autoloads powershell analyzer
> and automatically loads a file.. in that file i have a region that i
> use to load the assembly dynamically, then other regions for various
> tests, so its as easy and highlighting some collapsed regions of code
> and pressing f5, and also typing adhoc expression you want to run
> against it.. another cool thing about this technique, is you can put
> breakpoints in the C# code you are testing..
>
> Karl
>
>
 

My Computer

Users Who Are Viewing This Thread (Users: 1, Guests: 0)