Apply Your Knowledge

   


Exercises

8.1 Access COM Components from a Serviced Component

Accessing COM components from a serviced component is the same as accessing COM components from any .NET application. However, the RCWs referenced by serviced components should be strongly named. In this exercise, you'll learn how to use the command-line options of the Type Library Importer tool to create a strongly named RCW and use it from a serviced component.

Estimated time : 20 minutes

  1. Launch a .NET command prompt by selecting Start, Programs, Microsoft Visual Studio .NET, Visual Studio .NET Tools, Visual Studio .NET Command Prompt.

  2. Inside the command prompt window, navigate to the folder that contains the MyCustomer.dll COM library.

  3. If you have already created the key file containing the public/private key pair in Step by Step 7.2 in Chapter 7, copy the key file 70310.snk to this directory. If you haven't created one before, issue the following command to create a pair of public/private keys:

     sn k 70310.snk 
  4. Now, enter this command line to run the Type Library Importer tool to create a strongly named RCW:

     tlbimp MyCustomer.dll /keyfile:70310.snk /out:NETSMyCustomer.dll 
  5. Create a Blank Solution named 310C08Exercises in the Visual Studio .NET IDE.

  6. Add a Visual Basic .NET Class library named Exercise8-1 to the solution.

  7. Right-click the References node in Solution Explorer and select Add Reference.

  8. Click the Browse button in the Add Reference dialog box. Browse to the NETSMyCustomer.dll file that you created in step 4 and click Open. Click OK to add the reference to the project.

  9. Add a reference to the System.EnterpriseServices library in the current project.

  10. In the Solution Explorer, rename the default Class1.vb to BalanceSC.vb .

  11. Open the BalanceSC.vb and replace the code with the following code:

     Imports System Imports System.EnterpriseServices Imports NETSMyCustomer Namespace Exercise8_1     Public Interface IBalanceSC         Function RetrieveBalance(_          ByVal custNumber As Short) As Decimal     End Interface     Public Class BalanceSC         Inherits ServicedComponent         Implements IBalanceSC         Public Function BalanceSC()         End Function         Public Function RetrieveBalance(_          ByVal custNumber As Short) As Decimal _          Implements IBalanceSC.RetrieveBalance             Dim b As Balances = New Balances()             RetrieveBalance = b.GetBalance(_              custNumber)         End Function     End Class End Namespace 
  12. Open the AssemblyInfo.vb file in the project and add the following Imports directive:

     Imports System.EnterpriseServices 
  13. Add assembly level attributes ApplicationName , Description and ApplicationActivation to the AssemblyInfo.vb as shown here:

     <Assembly: ApplicationName(_  "Customer Balance Application")> <Assembly: Description("Retrieves the " & _  "customer balance from a COM component")> <Assembly: ApplicationActivation(_  ActivationOption.Library)> 
  14. Copy the 70310.snk key pair file to the solution folder. Change the AssemblyVersion and AssemblyKeyFile attributes in the AssemblyInfo.vb file as shown here:

     <Assembly: AssemblyVersion("1.0")> <Assembly: AssemblyKeyFile(_   "..\..\..310.snk")> 
  15. Build the project. Exercise8-1.dll is generated, and a strong name is assigned to the file based on the specified key file.

  16. Launch Visual Studio .NET command prompt and change the directory to the folder where the DLL file generated in step 15 resides. Issue the following command to install the assembly to the GAC:

     gacutil /i Exercise8-1.dll 
  17. In the command prompt, issue the following command to install the service component assembly to the COM+ Catalog:

     regsvcs Exercise8-1.dll 
  18. Add a new Visual Basic .NET Windows application named Exercise8-1Test to the solution.

  19. Add references to the System.EnterpriseServices library and Exercise8-1 project in the current project.

  20. Rename the form Form1 to Balance . Switch to code view and change all occurrences to Form1 to refer to Balance instead.

  21. Place two Label controls, two TextBox controls ( txtCustomerNumber and txtBalance ), and a Button control ( btnGetBalance ), on the form. Arrange the controls as shown in Figure 8.5.

    Figure 8.5. Design of a form that calls the BalanceSC serviced component.

  22. Switch to code view and add the following Imports directive:

     Imports Exercise8_1 
  23. Double-click the Button control and add the following code to its Click event handler:

     Private Sub btnGetBalance_Click(_  ByVal sender As System.Object, _  ByVal e As System.EventArgs) _  Handles btnGetBalance.Click     Dim bsc As Exercise8_1.Exercise8_1. _      BalanceSC = _      New Exercise8_1.Exercise8_1. _      BalanceSC()     Dim custNumber As Integer = _      Int16.Parse(_      txtCustomerNumber.Text)     txtBalance.Text = _      bsc.RetrieveBalance(_      custNumber).ToString() End Sub 
  24. Set the form as the startup form for the project, and set Exercise8-1Test as the startup project.

  25. Run the project. Enter a value between 1 to 10 in the first text box and click the Get Balance button to see that customer's balance. The balance is retrieved by a method call to the serviced component that in turn retrieves the balance from a method call to a COM component.

Review Questions

1:

Name some reasons to use COM components in a .NET project.

A1:

You might use COM components in a .NET project because you need to migrate an existing application in small pieces or because the COM components contain unique functionality for which you do not have source code.

2:

What is the purpose of an RCW?

A2:

RCWs provide a proxy between .NET applications and COM components. The RCW translates .NET calls into COM calls and returns the COM results as .NET results.

3:

How do you create an RCW?

A3:

You can create an RCW by using the Type Library Importer tool or by adding a direct reference to the COM component.

4:

What should you consider when choosing how to create an RCW?

A4:

When deciding how to create an RCW, you should consider whether you own the source code for the COM component, whether the RCW needs to go into the GAC, and how many .NET applications will make use of the COM component.

5:

What's the difference between COM interoperability and platform invoke?

A5:

COM interoperability allows you to instantiate COM classes within a .NET application and to invoke their members . Platform invoke allows you to call functions from a DLL.

6:

What does the CharSet.Auto parameter in a DllImport attribute specify?

A6:

The CharSet.Auto parameter of the DllImport attribute tells the CLR to choose the correct versionANSI or Unicodeof an API for the particular platform on which you are running the code.

Exam Questions

1:

Your application uses a COM component stored in a file named ProcessOrders.dll . You deploy the application via xcopy to the test server. Testers report that the orders are not being processed . The test server does have the .NET Framework installed. What could be the problem?

  1. The RCW for the COM component needs to be registered on the problem computers.

  2. ProcessOrders.dll is not stored in the Windows System directory.

  3. The problem computers are not connected to the Internet.

  4. Service Pack 1 for the .NET Framework is not installed on the problem computers.

A1:

A. RCWs can be installed by xcopy , just like any other .NET assemblies. .NET does not require the Internet to run, nor do RCWs depend on Service Pack 1. When you add RCW to an application, you must make sure that that COM component is registered in the Windows Registry of the target computers. For more information, see the section "Using COM Components" in this chapter.

2:

Your colleague needs to make a call to a COM component named TriState.dll from a serviced component registered as a COM+ server application. You suggest that she use the Type Library Importer tool. What command-line option should you suggest so that the serviced component is capable of accessing the methods of the COM component?

  1. Use the /keyfile option to assign a strong name to the COM component.

  2. Use the /reference option to set the reference to the serviced component.

  3. Use the /primary option to produce a primary interop assembly.

  4. Use the /unsafe option to disable the .NET Framework security checks.

A2:

A. The RCWs referenced by serviced components should be strongly named. Therefore, with the given choices, you need to select the /keyfile command-line option of the tlbimp.exe tool. The /keyfile option is passed a filename that contains the public/private key pair to strongly sign an assembly.

3:

You are responsible for migrating an existing COM application to Visual Basic .NET. The existing application consists of eight COM server components and a single client user interface component that instantiates and invokes objects from the server components. You want to give the user interface of the application an overhaul and migrate to Visual Basic .NET with low risk and minimal downtime. How should you proceed?

  1. Completely rewrite the entire application, using Visual Basic .NET.

  2. Bring only the user interface code into Visual Basic .NET. Use COM interoperability to call the existing COM servers from the .NET user interface code. Migrate the servers one by one.

  3. Bring all the servers into Visual Basic .NET. Use COM interoperability to call the migrated servers from the existing user interface code.

  4. Cut and paste all the existing code into Visual Basic .NET.

A3:

B. Moving all the code takes longer than moving part of the code, and it introduces additional risk. Because you'd like to rewrite the user interface, you should move that component to .NET before moving the server components.

4:

Your company supplies a COM component to provide advanced data analysis for your clients. Some of your clients are moving to the .NET Framework and require an RCW for your component. How should you proceed?

  1. Use the ActiveX Library Importer tool to create and sign a PIA for your component.

  2. Use the Type Library Importer tool to create and sign a PIA for your component.

  3. Set a reference to your component from any Visual Basic .NET project to create an RCW for your component.

  4. Create a class that uses platform invoke to call functions from your component.

A4:

B. As the vendor of the component, it's your responsibility to supply the PIA.

5:

You wrote a COM component to supply random numbers in a specific distribution to a simple statistical client program. Now you're moving that client program to the .NET Framework. The COM component is used nowhere else, and you have not shipped copies to anyone else. You want to call the objects in the COM server from your new .NET client. How should you proceed?

  1. Set a direct reference from your .NET client to the COM server.

  2. Use the Type Library Importer tool to create an unsigned RCW for the COM component.

  3. Use the Type Library Importer tool to create a signed RCW for the COM component.

  4. Use platform invoke to instantiate classes from the COM component.

A5:

A. For components you wrote that are used in a single project, the simplest method of creating the RCW is best.

6:

You have written several applications for your own use, all of which share classes from a COM component that you also wrote. You are moving the applications to .NET, but you intend to leave the COM component untouched. How should you proceed?

  1. Set a direct reference from each application to the existing COM component.

  2. Use the Type Library Importer tool to create an unsigned RCW for the COM component. Place a copy of this RCW in each application's directory.

  3. Use platform invoke to call functions from the existing COM component in each application.

  4. Use the Type Library Importer tool to create a signed RCW for the COM component. Place this RCW in the GAC.

A6:

D. Shared libraries should be placed in the GAC. Code must be signed before it can be placed in the GAC, and only the Type Library Importer tool can sign an RCW.

7:

Your .NET Remoting object needs to use a communications library from a third-party developer. This library is implemented as a COM component. What should you do to continue to use the classes and methods in the communications library?

  1. Obtain a PIA from the developer of the library. Install the PIA in the GAC.

  2. Use the Type Library Importer tool to create a signed RCW for the library. Install the RCW in the GAC.

  3. Use the Type Library Importer tool to create an unsigned RCW for the library. Install the RCW in the GAC.

  4. Create wrapper code that uses platform invoke to call functions from the library. Import this wrapper code into your application.

A7:

A. Because you did not write the code for the communications library, the proper way to proceed is to obtain a PIA from the original author.

8:

Your Visual Basic ASP.NET Web service uses functions from a Visual Basic 6 COM library implemented as a DLL via an RCW. You built the RCW by directly referencing the COM DLL. Users are complaining of poor performance. Which of these changes is most likely to improve the performance of your application?

  1. Recompile the Visual Basic 6 library as an EXE file.

  2. Switch your .NET application from Visual Basic .NET to Visual C# .NET.

  3. Use the Type Library Importer tool to create a new RCW.

  4. Rewrite the Visual Basic 6 library as a native .NET library.

A8:

D. Changing from a DLL to an EXE file or from Visual C# .NET to Visual Basic .NET has no significant effect on performance. RCWs are the same no matter how they're created. But rewriting the library into .NET is likely to speed it up because it eliminates the extra calls in the proxy layer.

9:

Your project contains the following API declaration:

 <DllImport("kernel32.dll", _  CharSet:=CharSet.Auto)>  Public Shared Function GetComputerName(_  ByVal buffer As String, _  size As Integer) As Integer 

The project also contains code to use this API to display the computer name:

 Public Sub ShowName()     Dim buf As String = ""     Dim intLen As Integer = 128     Dim intRet As Integer     ' Call the Win API method     intRet = GetComputerName(buf, intLen)     Console.WriteLine(_      "This computer is named " & _       buf.ToString()) End Sub 

Users report that no computer name is displayed. What should you do?

  1. Use ByRef with the variable buf in the call to the GetComputerName() function.

  2. Tell the users that their computers have no names set in their network properties.

  3. Replace the use of String with StringBuilder in the code.

  4. Use out with the variable buf in the call to the GetComputerName() function.

A9:

C. In the platform invoke calls, you should use StringBuilder instead of String to hold a string buffer that expects to be modified by the function.

10:

You want to use an unmanaged DLL named Balance.dll in your Visual Basic .NET application. Balance.dll does not provide any COM interfaces. How can you call the RetrieveBalance function of this library in your .NET code?

  1. Use the Type Library Importer tool.

  2. Use the Windows Forms ActiveX Control Importer tool.

  3. Use the DllImport attribute to declare the method RetrieveBalance from Balance.dll .

  4. Add a reference to the Balance.dll library in your Visual Studio .NET project.

A10:

C. Only the PInvoke feature of .NET allows you to call functions from unmanaged DLLs that do not provide any COM interfaces. Therefore, you need to use the DllImport attribute, which tells the .NET Framework where to find the implementation of a method call.

11:

You are using three classes from a COM component in your Visual Basic .NET application. You'd like to give the RCW for the COM component the same version number as the rest of your components when you ship the application. What should you do?

  1. Use platform invoke to call functions from the COM component, thus eliminating the RCW.

  2. Directly import the COM component into the References list. Right-click the reference and select Properties to set the version number.

  3. Recompile the existing COM library with the desired version number before creating the RCW.

  4. Use the Type Library Importer tool with the /asmversion option to explicitly set the version of the RCW.

A11:

D. Only the Type Library Importer tool can explicitly set the version number for an RCW.

12:

You are planning to use two classes from a COM component in your .NET application. You'd like to place these two classes into a namespace named ComComponents . What must you do?

  1. Set a direct reference to the COM component. Create an empty class file in your .NET project. Specify the ComComponents namespace in that file and import the wrapper class.

  2. Use the Type Library Importer tool with the /namespace option to set the namespace within the RCW.

  3. Use the Type Library Importer tool with the /out option to create a file with the desired name.

  4. Use platform invoke within a Namespace declaration to import the classes.

A12:

B. Only the Type Library Importer tool can set the namespace for an RCW.

13:

Your application will use functions from a COM component that uses COM+ services such as object pooling and just-in-time activation. Which of these methods can you use to access the classes in the COM component? (Select the two best answers.)

  1. Use platform invoke to declare the functions within the COM component.

  2. Add the COM component directly to the Visual Studio .NET toolbox.

  3. Set a direct reference to the COM component in your Visual Studio .NET project.

  4. Use the Type Library Importer tool to create an RCW for the COM component.

A13:

C and D. You can use COM components that use COM+ services by using the same techniques that you use with COM components.

14:

You have an existing COM component that contains shared classes. These classes encapsulate functionality that you want to use in your .NET application. How can you use these classes while maintaining the benefits of managed code, such as type safety and automatic garbage collection?

  1. Use the Type Library Importer tool with the /strictref option to create an RCW for the COM component.

  2. Call the methods from the COM component directly via platform invoke.

  3. Add a direct reference to the COM component.

  4. Rewrite the COM component as a .NET component.

A14:

D. Only managed code benefits from the features of the CLR. The only way to turn the component into managed code is to rewrite it in .NET.

15:

Your application uses the GetComputerName API function. This function exists in kernel32.dll in both ANSI and Unicode versions. Your declaration is as follows :

 <DllImport("kernel32.dll")> _ Public Shared Function GetComputerName(_ buffer As StringBuilder, size As Integer) _ As Integer 

Your code is failing with a System.EntryPointNotFoundException exception when you call this function. What should you do to fix this failure?

  1. Supply the full path for kernel32.dll .

  2. Add the CharSet.Auto parameter to the declaration.

  3. Declare the function as GetComputerNameA instead of GetComputerName .

  4. Declare the function as GetComputerNameW instead of GetComputerName .

A15:

B. The CharSet.Auto parameter is necessary to tell the CLR to use the ANSI or Unicode versions of the function as appropriate to the operating system.

Suggested Readings and Resources

1. Visual Studio .NET Combined Help Collection, "Interoperating with Unmanaged Code."

2. Adam Nathan. .NET and COM: The Complete Interoperability Guide . Sams, 2002.

3. Andrew Troelsen. COM and .NET Interoperability . Apress, 2002.


   
Top


MCAD. MCSD Training Guide (Exam 70-310. Developing XML Web Services and Server Components with Visual Basic. NET and the. NET Framework)
MCAD/MCSD Training Guide (70-310): Developing XML Web Services and Server Components with Visual Basic(R) .NET and the .NET Framework
ISBN: 0789728206
EAN: 2147483647
Year: 2002
Pages: 166

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