Making Remote File Access More Flexible

In the previous section, you created a web service that lets you retrieve a file from the server’s Documents folder. Rather than restrict the web service to files that reside within a specific folder, you will likely want your web service to be able to retrieve files that reside throughout a disk. Unfortunately, to provide a web service with such flexibility may require that you change a wide range of file permissions on your server—which would make your system less secure.

As an alternative, you can create a web service that requests a Windows service to copy files that reside on your hard disk into a specific folder that the web service can access. In other words, you will use two programs: a web service and a Windows service. The Windows service will wait to receive requests from the web service for a specific file. After the service receives the request, it will copy the requested file into the folder that the web service makes available to client programs.

The Visual Basic .NET program in Listing 13.3, PlaceFileCopy.vb, implements a Windows service that monitors the server’s Request folder (which you must create) for a new file. The program uses a FileSystemWatcher to monitor the Request folder for new files. After the service identifies a new file (when the Created event occurs), the OnCreated subroutine opens the file’s contents to determine the name of the file the user desires. Then, the service copies the file the user desires into the server’s Download folder. To create the PlaceFileCopy.vb Windows service, perform these steps:

  1. Within Visual Studio .NET, select the File menu New Project option. Visual Studio .NET will display the New Project dialog box.

  2. Within the New Project dialog box Project Types list, click Visual Basic Projects. Then, within the Templates field, click Windows Service. Finally, within the Location field, specify the folder within which you want to store the program. Likewise, within the Name field, specify PlaceFileCopy. Select OK. Visual Studio .NET will display the service’s Design View page.

  3. Right-click your mouse within the Design View window. The Visual Studio will display a popup menu.

  4. Within the popup menu, select Properties. The Visual Studio will display the service’s properties.

  5. Within the property list, assign the name PlaceFileCopy to the Service name property (not the Name property). Next, set to true the settings, shown in Figure 13.2, that enable the service to respond to PauseAndContinue, Stop, and Shutdown events.

    click to expand
    Figure 13.2: Assigning a Windows service’s name and attributes

  6. Click on the Code View option to display the service’s source code. Within the source-code window, enter the program statements in Listing 13.3.

Listing 13.3 PlaceFileCopy.vb

start example
Imports System.IO     Private WithEvents FileWatch As FileSystemWatcher     Protected Sub OnCreated(ByVal From As Object, _       ByVal e As FileSystemEventArgs) Handles FileWatch.Created         Dim Log As New EventLog("Application")         Log.Source = "PlaceFileCopy"         Log.WriteEntry("File " & e.FullPath & _         Ä " processed at " & DateTime.Now)         Log.Close()         Dim InputFile As FileStream         Dim TargetFileName As String         Dim FileLength As Long         Try             InputFile = File.Open(e.FullPath, FileMode.Open, _ Ä           FileAccess.Read)             FileLength = InputFile.Length             Dim DataBuffer(FileLength - 1) As Byte             InputFile.Read(DataBuffer, 0, FileLength)             InputFile.Close()             Dim I As Integer             For I = 0 To DataBuffer.Length - 1                 TargetFileName = TargetFileName + Chr(DataBuffer(I))             Next             File.Copy(TargetFileName, "C:\Documents\"  & _ Ä            Path.GetFileName(TargetFileName))             Dim ResultLog As New EventLog("Application")             ResultLog.Source = "PlaceFileCopy"             ResultLog.WriteEntry("File " & TargetFileName & _             Ä " successfully copied at " & DateTime.Now)             ResultLog.Close()         Catch Ex As Exception             Dim ResultLog As New EventLog("Application")             ResultLog.Source = "PlaceFileCopy"             ResultLog.WriteEntry("Error copying " & TargetFileName & _             Ä   " " & DateTime.Now & " " & Ex.Message)             ResultLog.Close()         End Try     End Sub     Protected Overrides Sub OnStart(ByVal args() As String)         Try             FileWatch = New FileSystemWatcher("C:\Request")             FileWatch.Filter = "*.*"             FileWatch.EnableRaisingEvents = True             Dim Log As New EventLog("Application")             Log.Source = "PlaceFileCopy"             Log.WriteEntry("PlaceFileCopy started at " & DateTime.Now)             Log.Close()         Catch E As Exception         End Try     End Sub     Protected Shadows Sub OnPause(ByVal args() As String)         Try             FileWatch.EnableRaisingEvents = False             Dim Log As New EventLog("Application")             Log.Source = "PlaceFileCopy"             Log.WriteEntry("PlaceFileCopy paused at " & DateTime.Now)             Log.Close()         Catch E As Exception         End Try     End Sub     Protected Shadows Sub OnContinue(ByVal args() As String)         Try             FileWatch.EnableRaisingEvents = True             Dim Log As New EventLog("Application")             Log.Source = "PlaceFileCopy"             Log.WriteEntry("PlaceFileCopy continued at " & _             ÄDateTime.Now)             Log.Close()         Catch E As Exception         End Try     End Sub     Protected Overrides Sub OnStop()         Try             FileWatch.EnableRaisingEvents = False             Dim Log As New EventLog("Application")             Log.Source = "PlaceFileCopy"             Log.WriteEntry("PlaceFileCopy stopped at " & DateTime.Now)             Log.Close()         Catch E As Exception         End Try     End Sub     Protected Shadows Sub OnShutdown(ByVal args() As String)         Try             FileWatch.EnableRaisingEvents = False             Dim Log As New EventLog("Application")             Log.Source = "PlaceFileCopy"             Log.WriteEntry("PlaceFileCopy shutdown at " & DateTime.Now)             Log.Close()         Catch E As Exception         End Try     End Sub
end example

As discussed, a Windows service is a special program you install within Windows. Using the Services window, you can start, pause, continue, and later stop the service. Each time you perform one of these operations, the service will call the corresponding subroutine. In this case, several of the subroutines simply record an entry within the system’s event log that describes the event. The OnStart subroutine, in contrast, also creates the FileSystemWatcher object and directs the object to monitor the Request folder for new files.

Before you can install a Windows service, you must add special additional code to your project that provides information Windows uses to install the service. To add code to the PlaceFileCopy service, perform these steps:

  1. Within Visual Studio .NET, select design view and then right-click on the design view window. Visual Studio .NET will display a popup menu.

  2. Within the popup menu, select Add Installer. Visual Studio .NET will add two components to your project: a service process installer and a service installer.

When you install a Windows service, Windows performs the installation using a user-level context that defines the server’s privileges. Using the service process installer, you must specify a user account on the system (or an account you create for the service) that defines the service’s context. To begin, right-click on the service process installer and select Properties from the popup menu. Within the installer’s properties fields, use the pull-down list to specify the account type as shown in Figure 13.3. Next, enter the username and password of the account you want the service to use.

click to expand
Figure 13.3: Specifying an account type, username, and password for the PlaceFileCopy service

Within the properties fields, you must first select the account type from the list of types specified in Table 13.1. Second, you must specify the username and password Windows will use to log into the account. If you do not specify the account context information, Windows cannot install the service.

Table 13.1:  Windows Account Types That Define the Service’s Context

Windows Account Type

Description

Local Service

Windows will run the service in the context of an account on the local system. The account may have extended privileges.

Local System

Windows will run the service in the context of a non-privileged account on the local system. The service will present anonymous credentials to a remote server.

Network Service

Windows will run the service in the context of a non-privileged account on the local system. The service will present the computer’s credentials to a remote server.

User

Windows will prompt the user for a valid username and password each time the service runs. Windows will run the service in the context of the specified user account.

Close the Service Process Installer Properties dialog box. Then, right-click the Service Installer icon. Visual Studio .NET will display the Service Installer Properties dialog box. Within the dialog box ServiceName field, type PlaceFileCopy as shown in Figure 13.4.

click to expand
Figure 13.4: Specifying the service name within the Service Installer Properties dialog box

Close the Service Installer Properties dialog box. You are now ready to build the service by selecting the Build menu Build PlaceFileCopy service option. After you successfully compile the service, you are ready to install the service for use by Windows, as discussed next.

Installing the PlaceFileCopy Windows Service

After you create a Windows service, you must direct Windows to install and run the service program as a background task each time your system starts. To install the service, you can use the InstallUtil program that Visual Studio .NET provides. The InstallUtil program is a command-line utility. To execute the InstallUtil command, you must specify the directory path on your system that contains the PlaceFileCopy.exe file. Pay close attention to the messages the InstallUtil program displays. If the utility cannot successfully install your service, the utility will display a message describing the cause of the error.

To direct Windows to install the PlaceFileCopy Windows service, select the Start menu Run option and type CMD to open the command window. Then, from the system prompt, issue the following InstallUtil command, replacing the directory path shown here with the path on your system that contains the PlaceFileCopy.exe program:

C:\> InstallUtil  C:\SomeDirectory\PlaceFileCopy.exe  <Enter>

After the InstallUtil command ends, your service will be installed within Windows, but it will not yet be running. To view and to start your service, perform these steps:

  1. Select the Start menu Settings options and choose Control Panel. Windows, in turn, will display the Control Panel window.

  2. Within the Control Panel, double-click the Administrative Tools icon. Windows will display the Administrative Tools window.

  3. Within the Administrative Tools window, double-click the Service’s icon. Windows will open the Services window, as shown in Figure 13.5.

    click to expand
    Figure 13.5: Using the Services window to start the PlaceFileCopy Windows service

  4. Within the Services window, right-click on the service you desire and then choose Start.

If, in the future, you no longer need the PlaceFileCopy service, you can use the InstallUtil command to remove the service, by including the /U switch:

C:\> InstallUtil  /U C:\SomeDirectory\PlaceFileCopy.exe  <Enter>

Using the PlaceFileCopy Windows Service

The GetAnyFile web service in Listing 13.4 uses the PlaceFileCopy Windows service to help a user retrieve a specific file from any folder on the user’s disk. The web service provides three methods:

  • The first, RequestFile, lets a program request a file from a specific directory. When the program calls the method, the method will create a file in the Request folder that contains the path of the file the user desires.

  • The second method, FileAvailable, returns a true or false value that specifies whether or not the Windows service has moved the specified file into the Documents folder.

  • Finally, the third method, GetFile, retrieves the specified file from the Documents folder, returning a byte array that contains the file’s contents:

    Boolean RequestFile(ByVal String) Boolean FileAvailable(ByVal String) Byte() GetFile(ByVal String)

To create the GetAnyFile web service, perform these steps:

  1. Within Visual Studio .NET, select the File menu New Project option. Visual Studio .NET will display the New Project dialog box.

  2. Within the New Project dialog box Project Types list, click Visual Basic Projects. Then, within the Templates field, click ASP.NET Web Service. Finally, within the Location field, specify the folder within which you want to store the program and the program name GetAnyFile. Select OK. Visual Studio .NET will display a page onto which you can drag and drop the service’s components.

  3. Select the View menu Code option. Visual Studio .NET will display the program’s source code. Within the source code add the program statements in Listing 13.4.

Listing 13.4 GetAnyFile.asmx.vb

start example
Imports System.IO <WebMethod()> Public Function RequestFile(ByVal Source As String) _    As Boolean    Dim OutputFile As New StreamWriter("C:\Request\" & Now.Ticks)    Try      OutputFile.Write(Source)      OutputFile.Close()      RequestFile = True    Catch Ex As Exception        RequestFile = False    End Try End Function <WebMethod()> Public Function FileAvailable(ByVal Source As String) _ ÄAs Boolean    FileAvailable = File.Exists("C:\Documents\" & _ Ä  Path.GetFileName(Source)) End Function <WebMethod()> Public Function GetFile(ByVal Source As String) As Byte()    Dim InputFile As FileStream    Dim FileLength As Long    Try      InputFile = File.Open(Path.GetFileName(Source), FileMode.Open, _      Ä FileAccess.Read)      FileLength = InputFile.Length      Dim DataBuffer(FileLength - 1) As Byte      InputFile.Read(DataBuffer, 0, FileLength)      InputFile.Close()      GetFile = DataBuffer    Catch Ex As Exception      Throw New Exception("Unable to open specified file")    End Try End Function
end example

The Visual Basic .NET program in Listing 13.5, SpecifyFileAndFolder.vb, uses the GetAnyFile web service to retrieve a file from a server. When you run the program, it will display a form similar to that shown in Figure 13.6 that prompts the user for the pathname of the desired file. After the user enters a pathname and clicks the Get File button, the program calls the web service to retrieve the file.

click to expand
Figure 13.6: Retrieving any file from a remote server

To create the SpecifyFileAndFolder.vb program, perform these steps:

  1. Within Visual Studio .NET, select the File menu New Project option. Visual Studio .NET will display the New Project dialog box.

  2. Within the New Project dialog box Project Types list, click Visual Basic Projects. Then, within the Templates field, click Windows Application. Finally, within the Location field, specify the folder within which you want to store the program and the program name SpecifyFileAndFolder. Select OK. Visual Studio .NET will display a form onto which you can drag and drop the program’s controls.

  3. Using the Toolbox, drag and drop the button and text boxes, list box, label, and hyperlink label previously shown in Figure 13.6 onto the page.

  4. Select the Project menu Add Web Reference option. Visual Studio .NET will display the Add Web Reference dialog box.

  5. Within the Address field, type localhost/GetAnyFile/Service1.asmx?WSDL and press Enter. The dialog box will load the file’s contents. Click the Add Reference button.

  6. Select the View menu Code option. Visual Studio .NET will display the program’s source code. Within the source code add the program statements in Listing 13.5.

Listing 13.5 SpecifyFileAndFolder.vb

start example
Imports System.IO Private Sub Button1_Click(ByVal sender As System.Object, _ Ä ByVal e As System.EventArgs) Handles Button1.Click   Dim DataFile As Byte()   Dim WS As New localhost.Service1()   Dim Filename As String = TextBox1.Text   If (Filename.Length > 0) Then     Try        If (WS.RequestFile(Filename)) Then          While (Not WS.FileAvailable(Filename))            TextBox2.Text = "Waiting for server to move file"          End While          DataFile = WS.GetFile(Filename)          Dim OutputFile As FileStream          Try            Filename = "C:\TEMP\" + Path.GetFileName(Filename)            OutputFile = File.Open(Filename, FileMode.Create, _            Ä FileAccess.Write)            OutputFile.Write(DataFile, 0, DataFile.Length)            OutputFile.Close()            TextBox2.Text = "File copied to C:\Temp"          Catch Ex As Exception            TextBox2.Text = "Error writing file " + Ex.Message          End Try        Else          TextBox2.Text = "Error requesting file"        End If      Catch Ex As Exception        TextBox2.Text = ex.Message      End Try    Else      TextBox2.Text = "Must specify file"    End If End Sub
end example

After a user types a pathname for a file on the remote server and then clicks the Get File button, the code will first call the web service’s RequestFile method that directs the Windows service that is running on the server to copy the file to the Documents folder. Then, the program code uses a While loop to wait until the Windows service moves the file. Finally, the program uses the web service’s GetFile method to retrieve the file. In this case, the program stores the file’s contents within the C:\Temp folder.




. NET Web Services Solutions
.NET Web Services Solutions
ISBN: 0782141722
EAN: 2147483647
Year: 2005
Pages: 161
Authors: Kris Jamsa

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net