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.
| 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 enables you to instantiate COM classes within a .NET application and to invoke their members. Platform Invoke enables you to call methods 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 version—ANSI or Unicode—of an API for the particular platform on which you are running the code. |
| 1: | Your application uses a COM component stored in a file named ProcessOrders.dll. You deploy the application via xcopy on 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?
The RCW for the COM component needs to be registered on the problem computers. ProcessOrders.dll is not stored in the Windows System directory. The problem computers are not connected to the Internet. Service Pack 1 for the .NET Framework is not installed on the problem computers.
|
|
A1:
| A. RCWs are 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 to her that she use the Type Library Importer tool. What command-line option should you suggest so that the serviced component can access the methods of the COM component?
Use the /keyfile option to assign a strong name to the COM component. Use the /reference option to set the reference to the serviced component. Use the /primary option to produce a primary interop assembly. Use the /unsafe option to disable the .NET Framework security checks.
|
|
A2:
| A. The RCW's 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. For more information, see the section "Using the Type Library Importer Tool (tlbimp.exe)" in this chapter. |
| 3: | You are responsible for migrating an existing COM application to Visual C# .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 application's user interface an overhaul and migrate to Visual C# .NET with low risk and minimal downtime. How should you proceed?
Completely rewrite the entire application, using Visual C# .NET. Bring only the user interface code into Visual C# .NET. Use COM interoperability to call the existing COM servers from the .NET user interface code. Migrate the servers one by one. Bring all the servers into Visual C# .NET. Use COM interoperability to call the migrated servers from the existing user interface code. Cut and paste all the existing code into Visual C# .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. For more information, see the section "Using COM Components" in this chapter. |
| 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?
Use the ActiveX Library Importer tool to create and sign a PIA for your component. Use the Type Library Importer tool to create and sign a PIA for your component. Set a reference to your component from any Visual C# .NET project to create an RCW for your component. Create a class that uses Platform Invoke to call methods from your component.
|
|
A4:
| B. As the vendor of the component, it's your responsibility to supply the PIA. For more information, see the section "Using COM Components" in this chapter. |
| 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?
Set a direct reference from your .NET client to the COM server. Use the Type Library Importer tool to create an unsigned RCW for the COM component. Use the Type Library Importer tool to create a signed RCW for the COM component. Use Platform Invoke to instantiate classes from the COM component.
|
|
A5:
| A. For components that are used in a single project, and that you wrote, the simplest method of creating the RCW is best. For more information, see the section "Using COM Components Directly" in this chapter. |
| 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?
Set a direct reference from each application to the existing COM component. 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. Use Platform Invoke to call methods from the existing COM component in each application. 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. For more information, see the section "Using COM Components" in this chapter. |
| 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?
Obtain a PIA from the developer of the library. Install the PIA in the GAC. Use the Type Library Importer tool to create a signed RCW for the library. Install the RCW in the GAC. Use the Type Library Importer tool to create an unsigned RCW for the library. Install the RCW in the GAC. Create wrapper code that uses Platform Invoke to call methods 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. For more information, see the section "Using COM Components" in this chapter. |
| 8: | Your Visual C# ASP.NET Web service uses methods 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 your application's performance?
Recompile the Visual Basic 6 library as an EXE file. Switch your .NET application from Visual C# .NET to Visual Basic .NET. Use the Type Library Importer tool to create a new RCW. 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 up performance because it eliminates the extra calls in the proxy layer. For more information, see the section "Using COM Components" in this chapter. |
| 9: | Your project contains the following API declaration:
[DllImport("kernel32.dll",
CharSet=CharSet.Auto)]
public static extern int GetComputerName(
String buffer, ref uint size);
The project also contains code to use this API to display the computer name:
public static void ShowName()
{
String buf = "";
UInt32 intLen=128;
Int32 intRet;
// Call the Win API method
intRet = GetComputerName(
buf, ref intLen);
Console.WriteLine(
"This computer is named " +
buf.ToString());
}
Users report that no computer name is displayed. What should you do?
Use the ref keyword with the variable buf in the call to the GetComputerName() method. Tell the users that their computers have no names set in their network properties. Replace the use of a String object with a StringBuilder object in the code. Use the out keyword with the variable buf in the call to the GetComputerName() method.
|
|
A9:
| C. In the Platform Invoke calls, you should use a StringBuilder object instead of a String object to hold a string buffer that expects to be modified by the method. For more information, see the section "Using Platform Invoke" in this chapter. |
| 10: | You want to use an unmanaged DLL named Balance.dll in your Visual C# .NET application. Balance.dll does not provide any COM interfaces. How can you call the RetrieveBalance() method of this library in your .NET code?
Use the Type Library Importer tool. Use the Windows Forms ActiveX Control Importer tool. Use the DllImport attribute to declare the extern method RetrieveBalance() from Balance.dll. 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 methods from unmanaged DLLs that do not provide any COM interfaces. Therefore, you need to use the DllImport attribute to tell the .NET Framework where to find the implementation of a method call. For more information, see the section "Using Platform Invoke" in this chapter. |
| 11: | You are using three classes from a COM component in your Visual C# .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?
Use Platform Invoke to call methods from the COM component, thus eliminating the RCW. Directly import the COM component into the References list. Right-click the reference and select Properties to set the version number. Recompile the existing COM library with the desired version number before creating the RCW. 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. For more information, see the section "Using the Type Library Importer Tool (tlbimp.exe)" in this chapter. |
| 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?
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. Use the Type Library Importer tool with the /namespace option to set the namespace within the RCW. Use the Type Library Importer tool with the /out option to create a file with the desired name. 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. For more information, see the section "Using the Type Library Importer Tool (tlbimp.exe)" in this chapter. |
| 13: | Your application will use methods 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.)
Use Platform Invoke to declare the methods within the COM component. Add the COM component directly to the Visual C# .NET toolbox. Set a direct reference to the COM component in your Visual Studio .NET project. Use the Type Library Importer tool to create an RCW for the COM component.
|
|
A13:
| C, D. You can use COM components that use COM+ services by using the same techniques that you use with COM components. For more information, see the sections "Using COM Components" in this chapter. |
| 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?
Use the Type Library Importer tool with the /strictref option to create an RCW for the COM component. Call the methods from the COM component directly via Platform Invoke. Add a direct reference to the COM component. 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. For more information, see the section "Using COM Components" in this chapter. |
| 15: | Your application uses the GetComputerName() API method. This method exists in kernel32.dll in both the ANSI and Unicode versions. Your declaration is as follows:
[DllImport("kernel32.dll")]
public static extern int GetComputerName(
StringBuilder buffer, ref uint size);
Your code is failing with a System.EntryPointNotFoundException exception when you call this method. What should you do to fix this failure?
Supply the full path for kernel32.dll. Add the CharSet.Auto parameter to the declaration. Declare the method as GetComputerNameA() instead of GetComputerName(). Declare the method 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 method as appropriate to the operating system. For more information, see the section "Using Platform Invoke" in this chapter. |