Project 1 - AppDomain (Console Application)
Program.cs
This project has no reference to Project 3 (FileLockFail). FileLockFail will not appear in the list of assemblies.
Unloading the created appDomain will release the file lock.
using System; using System.Reflection; using Interfaces; using System.IO; namespace ConsoleApplication1 { class Program { private const string targetDllName = "FileLockFail.dll"; static void Main(string[] args) { string testFileFullPath = CreateTestFile(); #if(DEBUG) //Copy the DDL that will be loaded into the AppDomain into the working directory. DirectoryInfo dllDir = new DirectoryInfo(Environment.CurrentDirectory); string source = Path.Combine(dllDir.Parent.Parent.Parent.FullName, @"FileLockFail\bin\Debug\" + targetDllName); string destination = Path.Combine(dllDir.FullName, targetDllName); File.Copy(source, destination, true); #endif AppDomainSetup domainSetup = new AppDomainSetup(); domainSetup.ApplicationName = "appDomain"; domainSetup.ApplicationBase = Environment.CurrentDirectory; AppDomain appDomain = AppDomain.CreateDomain("appDomain", null, domainSetup); ITestMethod otherDomainTestClass = (ITestMethod)appDomain.CreateInstanceAndUnwrap( targetDllName.Replace(".dll", ""), "FileLockFail.FailToCloseFileStream"); otherDomainTestClass.TestMethod(testFileFullPath); try { //This should fail due to the file lock still being open. System.IO.File.Delete(testFileFullPath); System.Diagnostics.Debug.Fail("Exception expected"); } catch (IOException) { AppDomain.Unload(appDomain); } System.IO.File.Delete(testFileFullPath); Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); Console.WriteLine("Assembly: {0}", AppDomain.CurrentDomain.FriendlyName); foreach (Assembly assembly in assemblies) { Console.WriteLine("Loaded: {0}.", assembly.ManifestModule.Name); } Console.WriteLine("Press enter"); Console.ReadLine(); } private static string CreateTestFile() { string filePath = Path.Combine(Environment.CurrentDirectory, "TestFile.txt"); using (FileStream fileStream = File.Create(filePath)) { using (System.IO.StreamWriter fileWriter = new StreamWriter(fileStream)) { fileWriter.Write("Hello World " + DateTime.Now); } } return filePath; } } }
Project 2 - Interfaces (Class Library)
ITestMethod.cs
Shared interface between both DLL's.
namespace Interfaces { public interface ITestMethod { void TestMethod(string message); } }
Project 3 - FileLockFail (Class Library)
FailToCloseFileStream.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; namespace FileLockFail { [Serializable] public class FailToCloseFileStream : MarshalByRefObject, Interfaces.ITestMethod { private static System.IO.FileStream _fileStream = null; public void TestMethod(string message) { Console.WriteLine("Host domain: {0} Message: {1}", AppDomain.CurrentDomain.FriendlyName, message); Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); Console.WriteLine("Assembly: {0}", AppDomain.CurrentDomain.FriendlyName); foreach (Assembly assembly in assemblies) { Console.WriteLine("Loaded: {0}.", assembly.ManifestModule.Name); } _fileStream = System.IO.File.OpenWrite(message); //Don't close the file stream } } }
See Also:
- Specify the path to a config file for the AppDomain MSDN: AppDomainSetup.ConfigurationFile
- Prevent the AppDomain locking the DLL using shadow copy - AppDomain and Shadow Copy