Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 55 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
55
Dung lượng
637,58 KB
Nội dung
Listing 24-10: Use the FileInfo Class to Delete Files with Ease using System; using System.IO; namespace rm { class Class1 { static void Main(string[] args) { string [] cla = Environment.GetCommandLineArgs(); if (cla.GetUpperBound(0) == 1) { FileInfo fi = new FileInfo(cla[1]); fi.Delete(); Console.WriteLine("File : " + cla[1]); Console.WriteLine("Attributes: " + fi.Attributes.ToString()); Console.WriteLine("File Deleted "); } else Console.WriteLine ("Usage: rm <filename>"); } } } As with the previous examples, you are storing the command-line arguments within a string array. If that array does not contain the correct number of elements, you simply display a usage message and exit. Tip By using the Delete() method of the FileSystemInfo class, you can delete directories as well as files. After calling the Delete() method of the FileInfo class, you can display the filename and its attributes to the user, indicating that it was deleted. Using the Attributes property, you can safely determine, before the file is deleted, if it has a Read-Only attribute set. If so, you can prompt the user and/or remove the Read-Only attribute using the Attributes property along with the FileAttributes enumerator. After your program is compiled, go to a command prompt and test it. Simply type rm followed by the filename to delete. The results should resemble those in Figure 24-6. Moving files The MoveTo() method of the FileInfo class actually encapsulates two different methods: CopyTo() and Delete(). After a file is copied to the appropriate filename or directory, MoveTo() simply deletes the file much as the Delete() method does. The following sample application accepts two command-line arguments: Source Filename and Destination Filename. After the file is moved, the program displays when the file was actually created and where the file was moved to. Neither of these outputs has a practical use except to demonstrate how the certain attributes can be obtained, such as the creation time using the CreationTime property. Figure 24-6: The Delete( ) method of the FileInfo class shows the attributes of the deleted file. Start a new C# console application and name this project mv, after the UNIX-based command of the same name. Listing 24-11 shows the application in its entirety. Listing 24-11: File Move Implementation using System; using System.IO; namespace mv { class Class1 { static void Main(string[] args) { string [] cla = Environment.GetCommandLineArgs(); if (cla.GetUpperBound(0) == 2) { FileInfo fi = new FileInfo(cla[1]); fi.MoveTo(cla[2]); Console.WriteLine("File Created : " + fi.CreationTime.ToString()); Console.WriteLine("Moved to : " + cla[2]); } else Console.WriteLine ("Usage: mv <source file> <destination file>"); } } } Figure 24-7 shows the output from your File Move utility. Figure 24-7: Move files with the MoveTo method of the FileInfo class. Note that in this example, the destination filename can be either a filename or a directory name. If a directory name is specified, the file is moved. If a filename is present, the file is renamed and/or moved. The MoveTo() method essentially incorporates copy and rename functions in one method. Accessing the Registry Registry access was rather burdensome with the Windows API. C# provides you with some class objects that enable you to read and write to and from the Registry with ease. Using the Registry provides several benefits over older methods, such as text-based INI files. Because the Registry is indexed, searching for keys is fast. The Registry is a structured "document," which allows for structured information, such as a database, just to name one type. Reading Registry keys Registry access functionality is contained within the Microsoft.Win32 namespace, so you need to include this namespace in all your projects by entering the following line at the top of your source code file: using Microsoft.Win32; To read a Registry key, you must use the RegistryKey object. To begin exploring this object, examine Listing 24-12, an application that retrieves two pieces of information from the Registry. Listing 24-12: Retrieve the CPU Type and Speed from the Registry using System; using Microsoft.Win32; namespace CPUInfo { class Class1 { static void Main(string[] args) { RegistryKey RegKey = Registry.LocalMachine; RegKey = RegKey.OpenSubKey( "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"); Object cpuSpeed = RegKey.GetValue("~MHz"); Object cpuType = RegKey.GetValue("VendorIdentifier"); Console.WriteLine("You have a {0} running at {1} MHz.",cpuType,cpuSpeed); } } } When instantiating an instance of the RegistryKey, you set it equal to a member of the Registry class. The preceding example sets the RegistryKey object equal to the Registry.LocalMachine field, which enables you access to the HKEY_LOCAL_MACHINE base key. Table 24-3 contains a list of all public fields within the Registry class. Table 24-3: Public Fields Within the Registry Class Field Description ClassesRoot ClassesRoot defines the types of documents and the properties associated with those types. This field starts in the Windows Registry from the key HKEY_CLASSES_ROOT. CurrentConfig CurrentConfig contains information pertaining to your computer's hardware. This field starts in the Windows Registry from the key HKEY_CURRENT_CONFIG. CurrentUser All preferences for the current user are stored here. This field starts in the Windows Registry from the key HKEY_CURRENT_USER. DynData DynData. LocalMachine LocalMachine contains configuration information for the computer. This field starts in the Windows Registry from the key HKEY_LOCAL_MACHINE. PerformanceData The base key stores performance-related information about the different software components. This field starts in the Windows Registry from the key HKEY_PERFORMANCE_DATA. Users This base key contains information that will be applied to a default user's configuration. This field starts in the Windows Registry from the key HKEY_USERS. After you establish your RegistryKey object, you call its OpenSubKey() method and provide the key that you want to open. In this particular case, you want to navigate to the HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\Central\Processor\0\ key and read two values from that key. Keep in mind that you must include double backslash characters in the string, so that they are not interpreted as an escape character. After you open the subkey, issue the following two lines of code to retrieve the "~MHz" and "VendorIdentifier" values within that subkey: Object cpuSpeed = RegKey.GetValue("~MHz"); Object cpuType = RegKey.GetValue("VendorIdentifier"); Now you have the values stored within the appropriate variables, so you can display the information on the screen. Test the program from a console window, as shown in Figure 24-8. Figure 24-8: The RegistryKey class simplifies the reading of important information from the Registry. Those of you running on multiple processor machines can obtain a list of all processors by enumerating the CentralProcessor key. You find a subkey within CentralProcessor for each CPU contained within your machine. Writing Registry keys Creating and writing Registry keys is also accomplished using the RegistryKey object. Several methods in the RegistryKey class are useful when writing keys. Table 24-4 describes the purpose of some of the more prevalent members. Table 24-4: Common RegistryKey Members Name Type Description SubKeyCount Property This property retrieves a count of the subkeys for the current key. ValueCount Property This property retrieves a count of the number of values for the current key. Close Method This method closes the current key. If changes have been made to the key, changes are flushed to disk. CreateSubKey Method This method creates a new subkey if one doesn't exist, or opens the subkey if it does exist. DeleteSubKey Method This method deletes a subkey. This method is overloaded and contains a Boolean parameter that allows an exception to be thrown if the key cannot be found. DeleteSubKeyTree Method This method deletes a subkey and all child subkeys recursively. DeleteValue Method This method deletes a value from a key. This method is overloaded and contains a Boolean parameter that allows an exception to be thrown if the value is missing. GetSubKeyNames Method This method returns a string array containing all subkey names. GetValue Method This method retrieves a value for a specific key. This method is overloaded and contains a parameter that permits a default value. If the value for a key is not found, the default value you specify will be returned. GetValueNames Method This method returns a string array containing all values for the specified key. OpenSubKey Method This method opens a subkey for processing (read/write access). SetValue Method This method sets a value for a key. To set the default value for a key, set the subKey parameter to an empty string. Caution Writing values can be dangerous and can cause your system to become unresponsive if care is not taken. Double-check all code before testing any application that writes values to the Registry. Listing 24-13 shows a simple application that writes two values to the Registry and then reads those values back in to display them. Listing 24-13: Write a Text and DWord Value to the Registry using System; using Microsoft.Win32; namespace WriteRegValues { class Class1 { static void Main(string[] args) { RegistryKey RegKeyWrite = Registry.CurrentUser; RegKeyWrite = RegKeyWrite.CreateSubKey ("Software\\CSHARP\\WriteRegistryValue"); RegKeyWrite.SetValue("Success","TRUE"); RegKeyWrite.SetValue("AttemptNumber",1); RegKeyWrite.Close(); RegistryKey RegKeyRead = Registry.CurrentUser; RegKeyRead = RegKeyRead.OpenSubKey ("Software\\CSHARP\\WriteRegistryValue"); Object regSuccessful = RegKeyRead.GetValue("Success"); Object regAttemptNumber = RegKeyRead.GetValue("AttemptNumber"); RegKeyRead.Close(); if ((string)regSuccessful == "TRUE") Console.WriteLine("Succeeded on attempt # {0}",regAttemptNumber); else Console.WriteLine("Failed!"); } } } After you create a RegistryKey object, you can create a new subkey with the CreateSubKey() method. Ensure that when using this method, you use double backslash characters, so the compiler doesn't interpret the characters as an escape sequence. In this example, you are creating a new key under HKEY_CURRENT_USER. Store your values in the \Software\CSHARP\WriteRegistryValue subkey. With the new key in place, use the SetValue() method to specify the name of the value and the actual value. This example, stores text in the Success value and a DWord in the AttemptNumber value. After the values are set, it's best to close the key in case of a power outage or similar failure. At this point, the changes have been committed to the Registry. If you open RegEdit and navigate to the proper key, you should see the values shown in Figure 24-9. Figure 24-9: RegEdit reveals that your values have been saved. As with the previous example, you now create a new RegistryKey object and read the values back in. If the Success value is in fact True, you display the information on the screen, as shown in Figure 24-10. Figure 24-10: Keys read from the Registry are displayed on the console. This application demonstrates a simple technique for writing values to the Registry. This method would prove useful for keeping track of program settings, recording the last position and size of your applications interface, and so on. The possibilities are endless. Enumerating Registry keys Enumerating Registry keys is a lot like the Find Files feature in Windows. It enables you to scan from any point in the Registry and retrieve all subkeys and values below that starting point. No methods are currently incorporated into .NET to enumerate Registry keys; it is up to you to build functions to support your needs. Knowing the structure of the keys you want to enumerate makes things much easier, as you can simply use a loop. If the structure of the Registry entries is unknown, you have to create a function that can call itself and pass the starting key in each time it is called. Listing 24-14 is an example of enumerating Registry keys. In this example, you scan the Registry for a list of all software installed on the computer. This program lists any application that shows up in the Add/Remove section of the Control Panel. Listing 24-14: Enumerating Registry Keys using System; using Microsoft.Win32; namespace Installed { class Class1 { static void Main(string[] args) { RegistryKey myRegKey=Registry.LocalMachine; myRegKey=myRegKey.OpenSubKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"); String [] subkeyNames = myRegKey.GetSubKeyNames(); foreach (String s in subkeyNames) { RegistryKey UninstallKey=Registry.LocalMachine; UninstallKey=UninstallKey.OpenSubKey ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + s); try { Object oValue=UninstallKey.GetValue("DisplayName"); Console.WriteLine(oValue.ToString()); } catch (NullReferenceException) { } } } } } After you have created a RegistryKey object, you open the Uninstall subkey, which contains a list of all programs installed. From here, you use GetSubKeyNames, which returns a string array of all subkeys. Now that you have your list of subkeys, you use the foreach operator to iterate through all elements in your subkey string array. When you iterate through each key, you search for a value called DisplayName. This DisplayName value is the name that is shown in the Add/Remove Programs section of the Control Panel. Remember that not all keys will have this value. Therefore, you must encapsulate your GetValue method with a try catch statement to catch any exceptions that may occur. After a DisplayName value is found, you retrieve the value and display it on the screen. The foreach statement then moves on to the next Registry key contained in the string array. Press F5 to try the application. You'll probably see a long list of applications scroll by as the program scans the Registry (see Figure 24-11). Figure 24-11: Scan all installed applications with a Registry enumerator. One thing that you did not tackle in this program is arranging the applications alphabetically. The items in the Registry are not stored in this manner, but to overcome this, you could simply store the results within a string array and call the Sort method to arrange the output in any manner allowed. Summary The .NET Framework has greatly reduced the amount of code and time it takes to effectively deal with files and the Windows Registry. Among the many benefits that the .NET Framework, you now have access to components such as the FileSystemWatcher which enables you to watch a file system for changes made to any file. You must take care, however, when writing applications that deal with the Windows Registry because accidentally removing Registry keys can cause your system to become unstable or even inoperable. Chapter 25: Accessing Data Streams In This Chapter The .NET Framework ships with classes that provide a high level of support for reading and writing data. Traditionally, languages have provided built-in support for reading and writing to disk-based files, and have relied on operating system programming interfaces to provide support for reading and writing to other types of data streams, such as network sockets or memory-based files. The .NET Framework unifies data I/O by providing a common set of classes that support data reads and writes regardless of the underlying storage mechanism used to provide the data access. All of these classes can be used from C# code. In this chapter, you learn to use streams. You learn how to use readers and writers to read data from and write data to a stream and how to perform file operations in the background. Understanding the Data I/O Class Hierarchy Figure 25-1 illustrates the class hierarchy for the basic .NET Framework classes used in data I/O work. The classes are grouped into one of three categories: streams, writers, and readers. Figure 25-1: Data I/O class hierarchy Using streams Stream classes provide a mechanism for referring to a data container. Stream classes share a common base class called Stream, which is defined in a .NET Framework namespace called System.IO. The Stream base class contains properties and methods that enable callers to work with the data stream. The .NET Framework ships with several classes that derive from the base Stream class. Each class provides a specific implementation of a data stream used for a particular environment. The FileStream class, for example, provides an imple- mentation that enables callers to work with streams of data tied to a disk-based file. Similarly, the NetworkStream class provides an implementation that enables callers to work with streams of data accessed over a network. Using writers [...]... console: C# code. > C# Bible Jeff Ferguson Wiley Summary Streams provide powerful support for both synchronous and asynchronous I/O for your C# applications Streams operate at the byte level and require you to read and write blocks of bytes... WriteXML() { XmlWriter = new XmlTextWriter(Console.Out); XmlWriter.WriteStartDocument(); XmlWriter.WriteComment("This XML document was automatically generated by C# code."); XmlWriter.WriteStartElement("BOOK"); XmlWriter.WriteElementString("TITLE", "C# Bible" ); XmlWriter.WriteElementString("AUTHOR", "Jeff Ferguson"); XmlWriter.WriteElementString("PUBLISHER", "Wiley"); } } XmlWriter.WriteEndElement(); XmlWriter.WriteEndDocument();... classes derived from the abstract TextWriter class, for example, enable your C# code to write text and have it encoded in the stream using ASCII, Unicode, UTF7, or UTF8 encoding algorithms Writing to streams with BinaryWriter Listing 25-4 shows the BinaryWriter class in action The job of the BinaryWriter class is to translate C# data types to a series of bytes that can be written to an underlying stream... Readers and writers encapsulate streams and provide access to data at a higher level You can use readers and writers to work with standard C# data types, enabling the readers and writers to translate between the data type values and their byte representations Your C# code will most likely work with readers and writers, as they provide support for working with the standard data types without forcing you... and work with shapes in your C# applications To get a complete picture of how to use GDI+ in your applications, you need to understand how to use the Graphics, Pen, Brush, and Color objects With these four objects, you can accomplish nearly anything you need to do with the GUI and images in NET This chapter explores these objects, and familiarizes you with using GDI+ in C# The available classes in GDI+... {0}", ReadInteger); Console.WriteLine("Double: {0}", ReadDouble); Console.WriteLine("String: {0}", ReadString); public void WriteBinaryData() { Writer.Write('a'); Writer.Write(123); Writer.Write(456. 789 ); Writer.Write("test string"); } } class MainClass { static public void Main() { FileTestClass FileTest = new FileTestClass(); } } FileTest.WriteBinaryData(); FileTest.ReadBinaryData(); Unlike the BinaryWriter... in the WriteBinaryData() method The values read from the stream are sent to the console Executing Listing 25-5 should produce the following output on the console: Character: a Integer: 123 Double: 456. 789 String: test string Writing Well-Formed XML Using the XmlWriter Stream Streams can do more than simply read from and write to various data streams They can also add value to the data being sent through... implementations translate the data type into a series of bytes and pass that translated byte stream to a Stream object This class design frees your code from having to deal with streams at the byte level Your C# application code can simply state, "write this unsigned long into the stream," for example, and enable the writer class to do the work needed to get the value stored into the stream as a series of bytes... FileTest.WriteBytes(); ReadTest = FileTest.ReadBytes(); if(ReadTest == true) Console.WriteLine("The readback test was successful."); else Console.WriteLine("The readback test failed."); Listing 25-1 implements two C# classes: FileTestClass, which contains the stream I/O code, and MainClass, which contains the application's Main() method The Main() method creates an object of the FileTestClass class and asks the... might not be ideal for your application Suppose, for example, that your application needs to write a series of integers to a stream Because integers in the 32-bit implementation are four bytes wide, your C# code would need to translate each integer into a string of four bytes that could be used in a call to the stream's implementation of Write() The NET Framework includes writer classes that support writing . information on the screen. Test the program from a console window, as shown in Figure 24 -8. Figure 24 -8: The RegistryKey class simplifies the reading of important information from the Registry one method. Accessing the Registry Registry access was rather burdensome with the Windows API. C# provides you with some class objects that enable you to read and write to and from the Registry. Delete( ) method of the FileInfo class shows the attributes of the deleted file. Start a new C# console application and name this project mv, after the UNIX-based command of the same name.