独立存储 独立存储 隔离的类型 如何:获取独立存储的存储区 如何:枚举独立存储的存储区 如何:删除独立存储中的存储区 如何:预见独立存储中的空间不足条件 如何:在独立存储中创建文件和目录 如何:在独立存储中查找现有文件和目录 如何:在独立存储中读取和写入文件 如何:在独立存储中删除文件和目录
不再需要指示应用程序的存储区域位置的硬编码信息。
数据隔离舱和存储区
如果没有标准的系统来处理这些问题,想开发出最大程度地减少存储冲突的特别技术可能并非易事,而且开发出来的技术也不见得可靠。
通过使用类似的凭据,数据还可以按应用程序域进行隔离。
独立存储还可以将信息和用户漫游配置文件一起存储在服务器上,这样,漫游用户就可以随时使用该信息。
安全访问
但是默认情况下,会对在本地计算机、本地网络或 Internet 中运行的代码授予使用独立存储的权限。
若要创建或访问独立存储,则必须授予代码相应的 IsolatedStorageFilePermission。
对于在 Web 上运行或从 Web 下载的代码而言,这种访问为之提供了一种读写与特定用户相关的存储区域的简便方法。
独立存储位置
您必须更改文件夹设置以显示隐藏文件和文件夹,才能查看到文件系统中的独立存储。
操作系统 |
在文件系统中的位置 |
---|---|
Windows 98、Windows Me - 未启用用户配置文件 |
支持漫游的存储区 = <SYSTEMROOT>Application Data 非漫游存储区 = WINDOWSLocal SettingsApplication Data |
Windows 98、Windows Me - 启用了用户配置文件 |
支持漫游的存储区 = <SYSTEMROOT>Profiles<用户>Application Data 非漫游存储区 = WindowsLocal SettingsApplication Data |
Windows NT 4.0 |
<SYSTEMROOT>Profiles<用户>Application Data |
Windows NT 4.0 - Service Pack 4 |
支持漫游的存储区 = <SYSTEMROOT>Profiles<用户>Application Data 非漫游存储区 = <SYSTEMROOT>Profiles<用户>Local SettingsApplication Data |
Windows 2000、Windows XP、Windows Server 2003 - 从 Windows NT 4.0 升级 |
支持漫游的存储区 = <SYSTEMROOT>Profiles<用户>Application Data 非漫游存储区 = <SYSTEMROOT>Profiles<用户>Local SettingsApplication Data |
Windows 2000 - 全新安装(和从 Windows 98 及 Windows NT 3.51 升级) |
支持漫游的存储区 = <SYSTEMDRIVE>Documents and Settings<用户>Application Data 非漫游存储区 = <SYSTEMDRIVE>Documents and Settings<用户>Local SettingsApplication Data |
Windows XP、Windows Server 2003 - 全新安装(和从 Windows 2000 及 Windows 98 升级) |
支持漫游的存储区 = <SYSTEMDRIVE>Documents and Settings<用户>Application Data 非漫游存储区 = <SYSTEMDRIVE>Documents and Settings<用户>Local SettingsApplication Data |
Windows Vista |
支持漫游的存储区 = <SYSTEMDRIVE>Users<用户>AppDataRoaming 非漫游存储区 = <SYSTEMDRIVE>Users<用户>AppDataLocal |
创建、枚举和删除独立存储
提供了三个主要的类来帮助您执行涉及独立存储的任务:
-
IsolatedStorageFile 类的实例表示位于文件系统中的单个存储区。
-
从 System.IO.FileStream 派生的 IsolatedStorageFileStream 提供对存储区中文件的访问。
-
IsolatedStorageScope 是一个枚举,使您可以创建并选择具有适当隔离类型的存储区。
独立存储工具 Storeadm.exe 也可以用于简单的存储区管理,例如列出或删除当前用户的所有存储区。
这些示例仅以 C# 的形式提供。
独立存储的情况
以下介绍了五种最典型的情况:
-
不允许从 Internet 下载的托管代码控件通过正常的 I/O 类写入硬盘,但它们可以使用独立存储来持久保存用户设置和应用程序状态。
-
应用程序间共享的组件可以使用独立存储来提供对数据存储区的有控制的访问。
-
在这种情况下,根据主体的标识隔离数据,该标识与应用程序用来区分其用户的标识是同一个标识。
-
这允许用户的独立存储区和配置文件一起漫游。
虽然独立存储非常适合于以上所述的情况,但在少数情况下,您“不”应该使用独立存储:
-
不要使用独立存储来存储重要机密(例如不加密的密钥或密码),因为独立存储对高度受信任的代码、非托管代码或计算机的受信任用户不设防。
-
不要使用独立存储来存储代码。
-
(因为管理员不控制用户首选项,所以用户首选项不被认为是配置设置。)
另外,当应用程序要求比数据库的行所提供的存储更加灵活和复杂的存储时,独立存储也可以提供一个可行的替代方案。
隔离的类型
虽然该标识是已验证身份的用户标识,但是模拟可以导致当前用户的标识动态地改变。
运行时以下面几种方式获得这些标识:
-
例如,如果可执行文件在路径 C:OfficeMyApp.exe 中运行,域标识可能为 C:OfficeMyApp.exe。
-
有关程序集和强名称的更多信息,请参见使用程序集编程。
-
有关漫游用户配置文件的更多信息,请参见 IsolatedStorageScope.Roaming。
将用户、域和程序集标识的概念结合起来,独立存储可以按下面几种方式隔离数据,每种方式都有其自己的使用情况:
有关更多信息,请参见独立和漫游。
下面的插图说明了如何将存储区隔离在不同的范围。
请注意,除了漫游存储区之外,独立存储始终被计算机隐式隔离,这是因为独立存储使用给定计算机本地的存储功能。
按用户和程序集隔离
调用 IsolatedStorageFile 的静态 GetStore 方法并传入用户和程序集 IsolatedStorageScope 将返回具有这种隔离的存储。
isoFile 对象访问该存储区。
IsolatedStorageFile isoFile = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null);
有关使用证据参数的示例,请参见 IsolatedStorageFile.GetStore(IsolatedStorageScope, Evidence, Type, Evidence, Type)。
此快捷方式无法用于打开能够漫游的存储区,在这种情况下,请使用 GetStore。
IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForAssembly();
按用户、域和程序集隔离
调用 IsolatedStorageFile 的静态 GetStore 方法并传入用户、域和程序集,IsolatedStorageScope 将返回具有这种隔离的存储。
isoFile 对象访问该存储区。
IsolatedStorageFile isoFile = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly, null, null);
此快捷方式无法用于打开能够漫游的存储区,在这种情况下,请使用 GetStore。
IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForDomain();
独立存储和漫游
如果未使用漫游范围,即使使用了漫游用户配置文件,存储区也不漫游。
示例
isoFile 对象访问该存储区。
IsolatedStorageFile isoFile = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly | IsolatedStorageScope.Roaming, null, null);
下面的代码示例对此进行了演示。
IsolatedStorageFile isoFile = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly | IsolatedStorageScope.Domain | IsolatedStorageScope.Roaming, null, null);
独立存储的配额
但是,由于代码可以通过表示不同的用户标识绕过权限配额,所以权限配额用作指导代码如何工作的指南,而不是对代码行为的硬性限制。
有关更多信息,请参见请求权限。
保护独立存储
每个 IsolatedStorageFilePermission 对象都具有指定以下值的属性:
允许的用法和安全风险
下表显示了权限中指定的允许的用法如何与隔离的类型对应,并总结了与每种允许的用法关联的安全风险。
允许的用法 |
隔离类型 |
安全影响 |
---|---|---|
无 |
不允许使用任何独立存储。 |
没有安全影响。 |
DomainIsolationByUser |
使用此权限的存储区也由计算机隐式隔离。 |
这叫做拒绝服务攻击。 |
DomainIsolationByRoamingUser |
则存储区保存到将漫游的位置。 |
因为必须禁用配额,所以存储资源更易受到拒绝服务攻击。 |
AssemblyIsolationByUser |
使用此权限的存储区也由计算机隐式隔离。 |
这就使信息可能在应用程序间泄露。 |
AssemblyIsolationByRoamingUser |
则存储区保存到将漫游的位置。 |
与前一个相同,但没有配额,增加了拒绝服务攻击的风险。 |
AdministerIsolatedStorageByUser |
通常,只有管理或调试工具才使用此级别的权限。 |
存在的风险包括(但不限于)泄露信息和数据丢失。 |
UnrestrictedIsolatedStorage |
才使用此级别的权限。 |
此权限有可能会整个危害所有用户的所有独立存储区。 |
如何:获取独立存储的存储区
下面的参数返回一个按用户、程序集和域隔离的存储区。
IsolatedStorageFile isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly | IsolatedStorageScope.Domain, null, null);
有关如何对此进行设置的详细信息,请参见独立存储和漫游。
有关更多信息,请参见 GetStore 方法。
一旦具有了独立存储文件对象之后,您便可以使用独立存储方法来读取、写入、创建和删除文件及文件目录了。
因此,使用这些引用的代码应该负责保护对 IsolatedStorageFile 对象的引用。
ObtainingAStore 示例
通过向 GetStore 方法传递的参数添加 IsolatedStorageScope.Domain,此代码可更改为检索按用户、域和程序集隔离的存储区。
有关 Storeadm.exe 的更多信息,请参见独立存储工具。
using System; using System.IO.IsolatedStorage; public class ObtainingAStore { public static void Main() { // Get a new isolated store for this assembly and put it into an // isolated store object. IsolatedStorageFile isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null); } }
如何:枚举独立存储的存储区
当使用 IsolatedStorageScope 值 User 进行调用时,GetEnumerator 返回为当前用户定义的 IsolatedStorageFiles 数组。
EnumeratingStores 示例
EnumerateTheStore 方法中,为了清楚起见,将该方法与代码的其他部分分开,放在文件的底部。
using System; using System.IO; using System.IO.IsolatedStorage; using System.Collections; public class EnumeratingStores { public static int Main() { // Get an isolated store for this assembly and put it into an // IsolatedStorageFile object. IsolatedStorageFile isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null); // This code creates a few files so that they can be enumerated. IsolatedStorageFileStream streamA = new IsolatedStorageFileStream("TestFileA.Txt", FileMode.Create, isoStore); IsolatedStorageFileStream streamB = new IsolatedStorageFileStream("TestFileB.Txt", FileMode.Create, isoStore); IsolatedStorageFileStream streamC = new IsolatedStorageFileStream("TestFileC.Txt", FileMode.Create, isoStore); IsolatedStorageFileStream streamD = new IsolatedStorageFileStream("TestFileD.Txt", FileMode.Create, isoStore); streamA.Close(); streamB.Close(); streamC.Close(); streamD.Close(); // There might be a small delay between when the above code // executes and when the files are created in the store. // Closing and opening the store in this example ensures that // the common language runtime has finished creating the files. isoStore .Close(); isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null); // This line of code calls a method at the bottom of the program // that puts all the files in isoStore into an IEnumerator. IEnumerator allFiles = EnumerateTheStore (isoStore); long totalsize = 0; // This code counts up the sizes of all the stores. while(allFiles .MoveNext()) { IsolatedStorageFile store = (IsolatedStorageFile)allFiles.Current; totalsize += (long)store.UsedSize; } Console.WriteLine("The total size = "+totalsize); return 0; } // This method returns an enumerator of all the files for a user. private static IEnumerator EnumerateTheStore(IsolatedStorageFile isoStore) { IEnumerator e = IsolatedStorageFile.GetEnumerator(IsolatedStorageScope.User); return e; } }
如何:删除独立存储中的存储区
IsolatedStorageFile 提供了两种删除独立存储文件的方法:
-
可以访问存储区的任何代码都可以删除该存储区中的任何数据或所有数据。
-
此操作需要 IsolatedStorageContainment 值 AdministerIsolatedStorageByUser 的 IsolatedStorageFilePermission 权限。
DeletingStores 示例
接下来,通过调用静态方法 IsolatedStorageFile.Remove,删除该用户其余的所有存储区。
using System; using System.IO.IsolatedStorage; public class DeletingStores { public static void Main() { // Get a new isolated store for this user, domain, and assembly. // Put the store into an IsolatedStorageFile object. IsolatedStorageFile isoStore1 = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly, null, null); Console.WriteLine("A store isolated by user, assembly, and domain has been obtained."); // Get a new isolated store for user and assembly. // Put that store into a different IsolatedStorageFile object. IsolatedStorageFile isoStore2 = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null); Console.WriteLine("A store isolated by user and assembly has been obtained."); // The Remove method deletes a specific store, in this case the // isoStore1 file. isoStore1.Remove(); Console.WriteLine("The user, domain, and assembly isolated store has been deleted."); // This static method deletes all the isolated stores for this user. IsolatedStorageFile.Remove(IsolatedStorageScope.User); Console.WriteLine("All isolated stores for this user have been deleted."); } // End of Main. }
如何:预见独立存储中的空间不足条件
但是,这不会妨碍您使用存储区的最大大小来确定是否将达到可用存储的上限。
以其他任何方式创建的 IsolatedStorageFile 对象(例如从 GetEnumerator 方法返回的对象)将无法返回准确的最大大小值。
示例
以字节数报告剩余的空间。
using System; using System.IO; using System.IO.IsolatedStorage; public class CheckingSpace { public static void Main() { // Get an isolated store for this assembly and put it into an // IsolatedStoreFile object. IsolatedStorageFile isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null); // Create a few placeholder files in the isolated store. new IsolatedStorageFileStream("InTheRoot.txt", FileMode.Create, isoStore); new IsolatedStorageFileStream("Another.txt", FileMode.Create, isoStore); new IsolatedStorageFileStream("AThird.txt", FileMode.Create, isoStore); new IsolatedStorageFileStream("AFourth.txt", FileMode.Create, isoStore); new IsolatedStorageFileStream("AFifth.txt", FileMode.Create, isoStore); Console.WriteLine(isoStore.AvailableFreeSpace + " bytes of space remain in this isolated store."); } // End of Main. }
如何:在独立存储中创建文件和目录
在存储区中,文件名和目录名是相对于虚文件系统的根目录指定的。
但是,如果您指定了包含无效字符的目录名称,则会生成 IsolatedStorageException。
IsolatedStorageFileStream 构造函数还可用于为其他目的打开文件。
当使用这种形式的构造函数时,文件是在该文件的域存储区中创建的。
显示时,文件名保持其原有的大小写。
CreatingFilesAndDirectories 示例
CreateDirectory 方法用于设置一些不同的目录,而 IsolatedStorageFileStream 方法则在这些目录中创建一些文件。
using System; using System.IO; using System.IO.IsolatedStorage; public class CreatingFilesDirectories { public static void Main() { // Get a new isolated store for this user, domain, and assembly. // Put the store into an IsolatedStorageFile object. IsolatedStorageFile isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly, null, null); // This code creates a few different directories. isoStore.CreateDirectory("TopLevelDirectory"); isoStore.CreateDirectory("TopLevelDirectory/SecondLevel"); // This code creates two new directories, one inside the other. isoStore.CreateDirectory("AnotherTopLevelDirectory/InsideDirectory"); // This file is placed in the root. IsolatedStorageFileStream isoStream1 = new IsolatedStorageFileStream("InTheRoot.txt", FileMode.Create, isoStore); Console.WriteLine("Created a new file in the root."); isoStream1.Close(); // This file is placed in the InsideDirectory. IsolatedStorageFileStream isoStream2 = new IsolatedStorageFileStream("AnotherTopLevelDirectory/InsideDirectory/HereIAm.txt", FileMode.Create, isoStore); isoStream2.Close(); Console.WriteLine("Created a new file in the InsideDirectory."); } // End of Main. }
如何:在独立存储中查找现有文件和目录
此外,Windows 文件系统中的文件和目录名不区分大小写。
*ect*/directory2 不是有效的搜索字符串。
对应用于 GetDirectoryNames 的搜索字符串中通配符的相同限制也适用于 GetFileNames。
SubSubDir。
FindingExistingFilesAndDirectories 示例
结果返回到数组中用于显示。
using System; using System.IO; using System.IO.IsolatedStorage; using System.Collections; using System.Collections.Generic; public class FindingExistingFilesAndDirectories { // Retrieves an array of all directories in the store, and // displays the results. public static void Main() { // This part of the code sets up a few directories and files in the // store. IsolatedStorageFile isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null); isoStore.CreateDirectory("TopLevelDirectory"); isoStore.CreateDirectory("TopLevelDirectory/SecondLevel"); isoStore.CreateDirectory("AnotherTopLevelDirectory/InsideDirectory"); new IsolatedStorageFileStream("InTheRoot.txt", FileMode.Create, isoStore); new IsolatedStorageFileStream("AnotherTopLevelDirectory/InsideDirectory/HereIAm.txt", FileMode.Create, isoStore); // End of setup. Console.WriteLine(' '); Console.WriteLine("Here is a list of all directories in this isolated store:"); foreach (string directory in GetAllDirectories("*", isoStore)) { Console.WriteLine(directory); } Console.WriteLine(' '); // Retrieve all the files in the directory by calling the GetFiles // method. Console.WriteLine("Here is a list of all the files in this isolated store:"); foreach (string file in GetAllFiles("*", isoStore)){ Console.WriteLine(file); } } // End of Main. // Method to retrieve all directories, recursively, within a store. public static List<String> GetAllDirectories(string pattern, IsolatedStorageFile storeFile) { // Get the root of the search string. string root = Path.GetDirectoryName(pattern); if (root != "") { root += "/"; } // Retrieve directories. List<String> directoryList = new List<String>(storeFile.GetDirectoryNames(pattern)); // Retrieve subdirectories of matches. for (int i = 0, max = directoryList.Count; i < max; i++) { string directory = directoryList[i] + "/"; List<String> more = GetAllDirectories(root + directory + "*", storeFile); // For each subdirectory found, add in the base path. for (int j = 0; j < more.Count; j++) { more[j] = directory + more[j]; } // Insert the subdirectories into the list and // update the counter and upper bound. directoryList.InsertRange(i + 1, more); i += more.Count; max += more.Count; } return directoryList; } public static List<String> GetAllFiles(string pattern, IsolatedStorageFile storeFile) { // Get the root and file portions of the search string. string fileString = Path.GetFileName(pattern); List<String> fileList = new List<String>(storeFile.GetFileNames(pattern)); // Loop through the subdirectories, collect matches, // and make separators consistent. foreach (string directory in GetAllDirectories("*", storeFile)) { foreach (string file in storeFile.GetFileNames(directory + "/" + fileString)) { fileList.Add((directory + "/" + file)); } } return fileList; } // End of GetFiles. }
如何:在独立存储中读取和写入文件
有关如何读写文件的进一步讨论,请参见 文件和流 I/O。
ReadingAndWritingToFiles 示例
然后,代码读取该文件并将结果输出到控制台。
using System; using System.IO; using System.IO.IsolatedStorage; public class ReadingAndWritingToFiles { public static int Main() { // Get an isolated store for this assembly and put it into an // IsolatedStoreFile object. IsolatedStorageFile isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null); // This code checks to see if the file already exists. string[] fileNames = isoStore.GetFileNames("TestStore.txt"); foreach (string file in fileNames) { if (file == "TestStore.txt") { Console.WriteLine("The file already exists!"); Console.Write("Type "StoreAdm /REMOVE" at the command line to delete all "); Console.WriteLine("Isolated Storage for this user."); // Exit the program. return 0; } } writeToFile(isoStore); Console.WriteLine("The file "TestStore.txt" contains:"); // Call the readFromFile and write the returned string to the //console. Console.WriteLine(readFromFile(isoStore)); // Exit the program. return 0; } // End of main. // This method writes "Hello Isolated Storage" to the file. private static void writeToFile(IsolatedStorageFile isoStore) { // Declare a new StreamWriter. StreamWriter writer = null; // Assign the writer to the store and the file TestStore. writer = new StreamWriter(new IsolatedStorageFileStream( "TestStore.txt", FileMode.CreateNew, isoStore)); // Have the writer write "Hello Isolated Storage" to the store. writer.WriteLine("Hello Isolated Storage"); writer.Close(); Console.WriteLine("You have written to the file."); } // End of writeToFile. // This method reads the first line in the "TestStore.txt" file. private static string readFromFile(IsolatedStorageFile isoStore) { // This code opens the TestStore.txt file and reads the string. StreamReader reader = new StreamReader(new IsolatedStorageFileStream( "TestStore.txt", FileMode.Open, isoStore)); // Read a line from the file and add it to sb. String sb = reader.ReadLine(); // Close the reader. reader.Close(); // Return the string. return sb.ToString(); } // End of readFromFile. }
如何:在独立存储中删除文件和目录
请记住,在存储区中,文件名和目录名是与操作系统相关的(在 Microsoft Windows 系统中通常不区分大小写),并且是根据虚文件系统的根目录具体而定的。
如果名称中包含有通配符,则 DeleteDirectory 会引发 IsolatedStorageFileException,而 DeleteFile 将引发 ArgumentException。
有关搜索存储区的虚文件系统的更多信息,请参见查找现有的文件和目录。
DeletingFilesAndDirectories 示例
下面的代码示例先创建若干个目录和文件,然后将它们删除。
using System; using System.IO.IsolatedStorage; using System.IO; public class DeletingFilesDirectories { public static void Main() { // Get a new isolated store for this user domain and assembly. // Put the store into an isolatedStorageFile object. IsolatedStorageFile isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly, null, null); Console.WriteLine("Creating Directories:"); // This code creates several different directories. isoStore.CreateDirectory("TopLevelDirectory"); Console.WriteLine("TopLevelDirectory"); isoStore.CreateDirectory("TopLevelDirectory/SecondLevel"); Console.WriteLine("TopLevelDirectory/SecondLevel"); // This code creates two new directories, one inside the other. isoStore.CreateDirectory("AnotherTopLevelDirectory/InsideDirectory"); Console.WriteLine("AnotherTopLevelDirectory/InsideDirectory"); Console.WriteLine(); // This code creates a few files and places them in the directories. Console.WriteLine("Creating Files:"); // This file is placed in the root. IsolatedStorageFileStream isoStream1 = new IsolatedStorageFileStream("InTheRoot.txt", FileMode.Create, isoStore); Console.WriteLine("InTheRoot.txt"); isoStream1.Close(); // This file is placed in the InsideDirectory. IsolatedStorageFileStream isoStream2 = new IsolatedStorageFileStream( "AnotherTopLevelDirectory/InsideDirectory/HereIAm.txt", FileMode.Create, isoStore); Console.WriteLine("AnotherTopLevelDirectory/InsideDirectory/HereIAm.txt"); Console.WriteLine(); isoStream2.Close(); Console.WriteLine("Deleting File:"); // This code deletes the HereIAm.txt file. isoStore.DeleteFile("AnotherTopLevelDirectory/InsideDirectory/HereIAm.txt"); Console.WriteLine("AnotherTopLevelDirectory/InsideDirectory/HereIAm.txt"); Console.WriteLine(); Console.WriteLine("Deleting Directory:"); // This code deletes the InsideDirectory. isoStore.DeleteDirectory("AnotherTopLevelDirectory/InsideDirectory/"); Console.WriteLine("AnotherTopLevelDirectory/InsideDirectory/"); Console.WriteLine(); } // End of main. }