home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 May / Chip_2000-05_cd1.bin / zkuste / Perl / ActivePerl-5.6.0.613.msi / 䆊䌷䈹䈙䏵-䞅䞆䞀㡆䞃䄦䠥 / _c4be8f8306b886e4367da03e5bb7290a < prev    next >
Text File  |  2000-03-22  |  40KB  |  899 lines

  1. <HTML>
  2.  
  3. <HEAD>
  4. <TITLE>Windows Script Components (WSC)</TITLE>
  5. <META name="GENERATOR" charset="iso-8859-1" content="Microsoft FrontPage 4.0">
  6. <META name="ProgId" content="FrontPage.Editor.Document">
  7. <LINK rel="STYLESHEET" href="../Active.css" type="text/css" media="screen">
  8. </HEAD>
  9.  
  10. <BODY bgcolor="#ffffff">
  11.  
  12. <TABLE border="0" cellpadding="0" cellspacing="0" width="100%">
  13.   <TR>
  14.     <TD class="block" valign="MIDDLE" width="100%" bgcolor="#cccccc"><STRONG>
  15.       <P class="block"> Windows Script Components</P>
  16.       </STRONG></TD>
  17.   </TR>
  18. </TABLE>
  19. <UL>
  20.   <LI><A href="#wsca">Windows Script Components (WSC)</A>
  21.     <UL>
  22.       <LI><A href="#com">The Component Object Model</A>
  23.       <LI><A href="#standardimplementation">A Standard And An Implementation</A>
  24.       <LI><A href="#parts">The Parts of A Component</A>
  25.         <UL>
  26.           <LI><A href="#comint">COM Interface</A>
  27.           <LI><A href="#comcls">COM Class</A>
  28.           <LI><A href="#comobj">COM Object</A>
  29.           <LI><A href="#comcom">COM Component</A>
  30.         </UL>
  31.       <LI><A href="#scraut">Scripting Languages And Automation</A>
  32.         <UL>
  33.           <LI><A href="#dispid">The Dispatch Interface</A>
  34.         </UL>
  35.       <LI><A href="#createwsc">Creating Windows Script Components</A>
  36.         <UL>
  37.           <LI><A href="#10steps">Ten Easy Steps</A>
  38.             <UL>
  39.               <LI><A href="#impps">Implementing the PerlScript</A>
  40.               <LI><A href="#regcom">Registering the Component</A>
  41.             </UL>
  42.           <LI><A href="#comprop">WSC with Properties and Notification</A>
  43.         </UL>
  44.       <LI><A href="#elementref">XML Element Reference</A>
  45.         <UL>
  46.           <LI><A href="#elemcom"><component></A>
  47.           <LI><A href="#elemreg"><registration></A>
  48.           <LI><A href="#elempub"><public></A>
  49.             <UL>
  50.               <LI><A href="#elemprop"><property></A>
  51.               <LI><A href="#elemmet"><method></A>
  52.               <LI><A href="#elemevent"><event></A>
  53.             </UL>
  54.           <LI><A href="#elemimp"><implements></A>
  55.           <LI><A href="#elemscr"><script></A>
  56.           <LI><A href="#elemobj"><object></A>
  57.           <LI><A href="#elemres"><resource></A>
  58.           <LI><A href="#elemref"><reference></A>
  59.           <LI><A href="#elemcomment"><comment></A>
  60.         </UL>
  61.     </UL>
  62.   <LI><A href="#author and copyright">AUTHOR AND COPYRIGHT</A>
  63. </UL>
  64. <HR>
  65. <a name="wsca"></a>
  66. <H1>Windows Script Components (WSC)</H1>
  67. <P>Windows Script Components (WSC), formerly known as Scriplets, is a technology 
  68.   for developing powerful COM components in an easy fashion. WSC's can be authored 
  69.   in any scripting language that has implemented the ActiveX Scripting Interfaces, 
  70.   which means that units of PerlScript code can be encapsulated as Windows Script 
  71.   Components.<BR>
  72.   <BR>
  73.   Be warned, reader, a lengthy introduction to the Component Object Model (COM) 
  74.   stretches until the topic of Windows Script Components. Please move directly 
  75.   to the topic of Windows Script Components if you feel that you understand the 
  76.   COM; the COM is essential to WSC, thus it is necessary to cover the fundamentals 
  77.   of the COM.<BR>
  78.   <a name="com"></a><BR>
  79. <H2>The Component Object Model</H2>
  80. <P>The Component Object Model (COM) is a language-independent and object-oriented programming model.
  81. It is not, however, a programming language, and it does not demand that a new style of programming
  82. be learned. It is a binary standard that enables software to be implemented as units called
  83. components. The component can be authored in any programming language or scripting language provided
  84. that the language supports the standard defined by the COM. After the binary unit has been built, it
  85. can communicate with other units that were produced in any other language, on the same machine or on
  86. remote machines provided that the units were written as COM components.<BR>
  87. <BR>
  88. As many see it, the Component Object Model is elegant and powerful. The basic yet ingenious
  89. programming model provides the foundation for application-development. The power resides in that
  90. everything built on the same foundation can communicate with each other without any restrictions
  91. such as programming languages or platforms. When developing an application devoted to COM,
  92. components should encapsulate every functionality that the application requires. A task performed by
  93. the application would be executed by a component, and these components would be reused in other and
  94. future applications. For example, a Perl-component can contain the process of sending an email or
  95. performing a series of regular expressions on text. The component can then be used to provide
  96. functionality for an Active Server Pages application or a Windows desktop application.<BR>
  97. <BR>
  98. In summary, although the language in which a component is generated may vary from component to
  99. component, a binary standard overcomes the limitation of programming in different languages. It does
  100. not care about anything else but the binary form of the machine code that the once source code was
  101. turned into and the fact that is implemented into COM. In this sense, the component is not a regular
  102. script or executable, but a black box that performs one task and returns the projected result.
  103. Multiple languages can be used for one application because COM provides a binary standard. A binary
  104. standard also results in platform-independence provided that multiple platforms support COM. Units
  105. of code that are used in COM are known as components, and on Windows a component is normally file
  106. with the extension .dll; however, there are offshoots such as Windows Script Components, which have
  107. the extension .wsc. The purpose of the component is to perform the one task that it has been
  108. programmed for, and through COM, it can communicate with other components, languages, and platforms.<BR>
  109. <BR>
  110. <A name="standardimplementation"></a>
  111. <H2>A Standard And An Implementation</H2>
  112. <P>COM is both a specification and an implementation. And being both a specification 
  113.   and an implementation, the COM defines a standard for how the components are 
  114.   created and how they communicate û namely as objects. As a result, the specification 
  115.   solves the implementation issues of the following key issues:<BR>
  116. <UL>
  117.   <LI>The calling of a component</LI>
  118.   <LI>The locating of a component</LI>
  119.   <LI>The identification of a component</LI>
  120.   <LI>The creation of a component</LI>
  121. </UL>
  122. Although the parts above are involved in the specification of how to implement 
  123. components, the programmer normally does not have to worry much about them. A 
  124. software development tool that holds high class will create a skeleton for a component, 
  125. and leave it up to the programmer only to plug in the code in the right places. 
  126. Thanks to this, the code itself can be developed, debugged, and experimented with 
  127. as usual. And then when the code is finished, it is placed in the skeleton, the 
  128. right buttons are clicked, and the component pops out.<BR>
  129. <A name="parts"></A> 
  130. <H2>The Parts of A Component</H2>
  131. <P>When wondering what makes up a component, recall that COM is an object-oriented programming model
  132. that requires every component to be implemented as an object, so from this we know that we will be
  133. talking about classes, methods, properties, and such entities that belong in an object-oriented
  134. programming model. However, letÆs start at the bottom level and move our way up from interfaces,
  135. to classes, and to objects.<BR>
  136. <BR>
  137. <A name="comint"></a>
  138. <H3>COM Interface</H3>
  139. When the component is implemented, it exposes its features through one or more interfaces. The
  140. interface is a specification of a collection of methods and properties that are related to each
  141. other, so when a component is called, it must be called through one of its interfaces. In general,
  142. this means that an interface relates to an operation such as verifying a credit-card number or
  143. sending an email. Because the component may expose several interfaces and the method-calls pass by
  144. way of the correct interface, the interface that is called must be identifiable. It is a fact that
  145. names easily clash, and especially with a high pace of component development, so another solution is
  146. provided. An interface uses a globally unique identifier (GUID) which is a 128-bit integer. And
  147. through the GUID, the interface is identified to the COM.<BR>
  148. <BR>
  149. <A name="comcls"></A>
  150. <H3>COM Class</H3>
  151. Next, the COM class implements, or maybe better ôinheritsö, one or more COM interfaces. A Class
  152. ID (CLSID) uniquely identifies the COM class, and while the interfaces are at the base level of the
  153. COM architecture, the COM class is on top of the interfaces - one step close to the application. The
  154. main purpose of the COM class is to generate, or instantiate, the COM object that represents the
  155. functionality of the unit of code.<BR>
  156. <BR>
  157. <A name="comobj"></A> 
  158. <H3>COM Object</H3>
  159. As previously mentioned, this part of COM simply is the instance of a COM class, or the entity from
  160. which all the features of the COM class are accessed.<BR>
  161. <BR>
  162. <A name="comcom"></A>
  163. <H3>COM Component</H3>
  164. In the midst of everything, where does the component fit into the picture? It can be easily
  165. summarized as that the component is used to include a COM class by identifying it by the CLSID,
  166. create an instance of the COM class as the COM object, and then let the application make use if the
  167. COM object on the machine.<BR>
  168. <BR>
  169. <A name="scraut"></A>
  170. <H2>Scripting Languages and Automation</H2>
  171. Scripting Languages and Automation Automation, formerly OLE automation, makes it easier for the
  172. masses to access COM object servers such as components. In terms of a scripting language, the only
  173. way for a COM component to make its features available is through Automation. Automation is one
  174. level higher up than COM, in other words one step closer to the application, and it is the
  175. technology that lets software packages such as Microsoft Office expose its functionality in an
  176. object-model for scripting languages that support Automation.<BR>
  177. <BR>
  178. In the same manner as large applications like MS Office are exposed, smaller COM components are made
  179. available to a scripting language through Automation, as well. Without it, the scripting language
  180. would necessarily have to know all the interfaces of an object that it wants to use before calling
  181. it û too much information to build into a language.<BR>
  182. <BR>
  183. Instead of bloating a language with junk, COM defines the standard for accessing COM object servers:
  184. Automation. In turn, Automation makes sure that a standard interface that allows, in our case,
  185. script-access to the component is always available for object-access. This standard interface used
  186. in Automation is called a dispatch interface, dispinterface, or automation interface.<BR>
  187. <BR>
  188. <A name="dispid"></A>
  189. <H3>The Dispatch Interface</H3>
  190. A dispatch interface is somewhat different than the standard COM interface. Methods are associated
  191. with dispatch IDs (dispids), and methods have been provided for reading and writing the values of
  192. properties û the access to the data members in the underlying data structure.<BR>
  193. <BR>
  194. The standard dispatch interface for automation is called IDispatch. Through IDispatch, a component
  195. can expose as much as it wants to expose. Then in order for Perl to gain access to components, the
  196. interpreter needs to support an object-oriented programming model, have the ability to call methods
  197. through IDispatch, know how to return errors, and be able to destroy objects.<BR>
  198. <BR>
  199. A method that belongs to an interface of a COM component is retrieved by the dispatch interface and
  200. in Perl this can occurs by what is known as late binding. A dispatch method called GetIDsOfNames is
  201. called with the name and the parameters of the method of the COM interface that is called. The
  202. dispatch ID of the method is returned. Next, the Invoke-method of IDispatch is called with all the
  203. processed information returned from GetIDsOfNames, and from that call the result is returned in an
  204. output parameter. This method is called late binding, and there are two things to notice about it:<BR>
  205. <UL>
  206.   <LI>there is an overhead involved in the Automation discussed</LI>
  207.   <LI>All data types that are sent as parameters through Invoke to the method of an interface must
  208.     be passed as Variants or converted into Variants.</LI>
  209. </UL>
  210. When not using late binding, the application already is aware of all the dispatch IDs and does not
  211. call GetIDsOfNames at all. This is called early binding since the information needed for using the
  212. components have been built into the application and are used at run-time.<BR>
  213. <BR>
  214. Perl uses late binding, and the process of late binding is simple. First, a moniker is required,
  215. which is a name that uniquely identifies the COM object. The moniker is then used to locate the
  216. object, which next is either in running state or put into running state. When in running state, the
  217. server application can access the interfaces of the COM object, and when that is completed, an
  218. interface pointer is returned to it. The dispatch interface that makes COM objects accessible to a
  219. scripting language is implemented as a COM interface that uses IDispatch. And the IDispatch
  220. functions of this interface only calls the methods that are laid out in the COM interface, and these
  221. two interfaces are called dual interfaces because an application that knows only early-binding can
  222. access it while another language that knows only late-binding can access it, as well.<BR>
  223. <BR>
  224. Although the implementation of all of the above hidden to Perl, there are some things to know. In
  225. most cases, Automation will accept and convert scalar data into the correct variant-type. However,
  226. it might be necessary to specify the type of data, and to solve this issue and convert Perl data
  227. types to the variants used.
  228. <P> </P>
  229. <TABLE width="360" valign="TOP">
  230.   <TR>
  231.     <TD width="60" valign="TOP">VT_EMPTY</TD>
  232.     <TD width="320" valign="TOP"><FONT color="#000000">No Value</FONT></TD>
  233.   </TR>
  234.   <TR>
  235.     <TD width="60" valign="TOP">VT_NULL</TD>
  236.     <TD width="320" valign="TOP"><FONT color="#000000">Null Value</FONT></TD>
  237.   </TR>
  238.   <TR>
  239.     <TD width="60" valign="TOP">VT_I2</TD>
  240.     <TD width="320" valign="TOP"><FONT color="#000000">2-byte integer</FONT></TD>
  241.   </TR>
  242.   <TR>
  243.     <TD width="60" valign="TOP">VT_I4</TD>
  244.     <TD width="320" valign="TOP"><FONT color="#000000">4-byte integer</FONT></TD>
  245.   </TR>
  246.   <TR>
  247.     <TD width="60" valign="TOP">VT_R4</TD>
  248.     <TD width="320" valign="TOP"><FONT color="#000000">4-byte real value</FONT></TD>
  249.   </TR>
  250.   <TR>
  251.     <TD width="60" valign="TOP">VT_R8</TD>
  252.     <TD width="320" valign="TOP"><FONT color="#000000">8-byte real value</FONT></TD>
  253.   </TR>
  254.   <TR>
  255.     <TD width="60" valign="TOP">VT_CY</TD>
  256.     <TD width="320" valign="TOP"><FONT color="#000000">Currency</FONT></TD>
  257.   </TR>
  258.   <TR>
  259.     <TD width="60" valign="TOP">VT_DATE</TD>
  260.     <TD width="320" valign="TOP"><FONT color="#000000">Date</FONT></TD>
  261.   </TR>
  262.   <TR>
  263.     <TD><BR>
  264.   <TR>
  265.     <TD width="60" valign="TOP">VT_BSTR</TD>
  266.     <TD width="320" valign="TOP"><FONT color="#000000">Binary string</FONT></TD>
  267.   </TR>
  268.   <TR>
  269.     <TD width="60" valign="TOP">VT_DISPATCH</TD>
  270.     <TD width="320" valign="TOP"><FONT color="#000000">Automation object</FONT></TD>
  271.   </TR>
  272.   <TR>
  273.     <TD width="60" valign="TOP">VT_ERROR</TD>
  274.     <TD width="320" valign="TOP"><FONT color="#000000">Error code</FONT></TD>
  275.   </TR>
  276.   <TR>
  277.     <TD width="60" valign="TOP">VT_BOOL</TD>
  278.     <TD width="320" valign="TOP"><FONT color="#000000">Boolean value</FONT></TD>
  279.   </TR>
  280.   <TR>
  281.     <TD width="60" valign="TOP">VT_VARIANT</TD>
  282.     <TD width="320" valign="TOP"><FONT color="#000000">Variant</FONT></TD>
  283.   </TR>
  284.   <TR>
  285.     <TD width="60" valign="TOP">VT_UNKNOWN</TD>
  286.     <TD width="320" valign="TOP"><FONT color="#000000">IUknown Pointer</FONT></TD>
  287.   </TR>
  288.   <TR>
  289.     <TD width="60" valign="TOP">VT_UI1</TD>
  290.     <TD width="320" valign="TOP"><FONT color="#000000">Unsigned 1-byte character</FONT></TD>
  291.   </TR>
  292.   <TR>
  293.     <TD><BR>
  294.   <TR>
  295.     <TD width="60" valign="TOP">VT_BYREF</TD>
  296.     <TD width="320" valign="TOP"><FONT color="#000000">Describes the data as passed by reference</FONT></TD>
  297.   </TR>
  298.   <TR>
  299.     <TD width="60" valign="TOP">VT_ARRAY</TD>
  300.     <TD width="320" valign="TOP"><FONT color="#000000">An OLE Safearray</FONT></TD>
  301.   </TR>
  302. </TABLE>
  303. <BR>
  304. In Perl, Automation and creation of Automation objects is provided by the Win32::OLE module,
  305. Furthermore, Variant data types can be converted by the Variant() method or the OLE module although
  306. Perl seamlessly takes care of most of the conversion needed.<BR>
  307. <BR>
  308. <A name="createwsc"></A>
  309. <H2>Creating Windows Script Component's</H2>
  310. When it comes to writing a WSC, it is a surprisingly quick and easy process. In fact, anybody who
  311. has written an ASP page with some script commands and HTML will have completed a WSC in less than
  312. five minutes. And although .wsc files are Extensible Markup Language (XML) files, no previous
  313. experience with XML is necessary in order to build a successful component.<BR>
  314. <BR>
  315. <A name="10steps"></A>
  316. <H3>Ten Easy Steps</H3>
  317. In order to create a WSC, you can use the Windows Script Component Wizard. The wizard will produce a
  318. valid skeleton for your WSC, and all you will have to do is enter your PerlScript. Let's create a
  319. simple WSC that can be instantiated within a script and holds the basic functionality of being
  320. passed a string and retuns the reversed string, so follow me on these steps.<BR>
  321. <ol>
  322.   <li> Open the Windows Script Component Wizard</li>
  323.   <li>Enter "Easy" in the component name-field; progID automatically 
  324.     becomes Easy.WSC, which is fine.</li>
  325.   <li>Click "Next"</li>
  326.   <li> Set the "Language"-option for the component to "Other" 
  327.     and enter "PerlScript"</li>
  328.   <li> Click "Next"</li>
  329.   <li> Click "Next" in the "Properties" window</li>
  330.   <li> Enter "SayHello" as a method with no parameters</li>
  331.   <li> Click "Next"</li>
  332.   <li> Click "Next" in the "Events" windows</li>
  333.   <li> Click "Finish" </li>
  334. </ol>
  335. <A name="impps"></A>
  336. <H4>Implementing the PerlScript</H4>
  337. Following the simple steps above will create a nice skeleton to hold your code. With the exception
  338. for the classid, which is unique each time one is generated, it will look as illustrated.<BR>
  339.  
  340.   
  341. <pre>
  342. <?xml version="1.0"?>
  343. <component>
  344.    <registration   
  345.     description="Easy"
  346.     progid="Easy.WSC"
  347.     version="1.00"
  348.     classid="{74bb1ba9-2e69-4ad6-b02c-c52f3cbe153b}"
  349.     >
  350.     </registration>
  351.  
  352.     <public> 
  353.         <method name="SayHello">
  354.         </method>   
  355.  
  356.     </public>
  357.  
  358.     <script language="PerlScript"><BR>
  359.         <![CDATA[
  360.  
  361.         ]]>
  362.     </script>
  363. </component>
  364. </pre>
  365.  As seen above, you have a Window Script Component that is an XML file. The first declaration of the WSC enables strict XML. In that mode, the elements and attributes are case-sensitive, and attribute values must be enclosed within single quotes or double quotes. You may omit the XML declaration on top of the document and it will not be compiled as strictly, but in these examples, we will stick with XML conformity and leave the declaration in each document. To note about XML elements is that they, like HTML, have end-tags like "<registration>" and "</registration>"; however, as you will see, you can replace the end-tag in some operations by simply writing "<registration/>".
  366. <P>
  367.  Secondly, you have a component element. This element is used to enclose each component. You will place one at the beginning, and one at the end. As an exception to the rule, there is an element that has a higher priority than the component, and that element must be used whenever you keep more than one component in your WSC file. Is is the package element. It will as a single element enclose all components; however, as mentioned, it is not required when you have one component within the file.
  368. <P> 
  369.  Next, the registration element contains the information about your component such as the progid, classid, description, and version number. Description is a string in which you can write a short abstract summary the funcitonality of your component. The progid is used by the program which creates an instance of your component, and the version number should be incremented if you release a new version of your component. The version number can also be appeneded to the progid as as Easy.WSC.1.00 when creating the instance of your component.
  370. <P> 
  371.  After the registration element, the data and functionality that the component expose are defined. The public element will hold properties, methods, and events. We declare a method by the name "SayHello" and then skip on down to the script-elements. As you can tell, there is no source code, so we need to fill that out. In the empty space, enter the following:
  372. <P>
  373. <pre>
  374. sub SayHello {
  375.     my($param) = shift @_;
  376.     return reverse($param);
  377. }
  378. </pre>
  379. <BR>
  380. Aside of the elements that we've covered, it should look as below.<BR>
  381. <pre>
  382. <script language="PerlScript">
  383.     <![CDATA[
  384.     sub SayHello {
  385.         my($param) = shift @_;
  386.         return reverse($param);
  387.     }
  388.     ]]>
  389. </script>
  390. </pre>
  391. <BR>
  392. <A name="regcom"></A>
  393. <H4>Registering the Component</H4>
  394. <p>Now, it's time to register the component on the system so that it can be used. 
  395.   There are two ways to do this and we assume that the file is saved as c:\easy.wsc.</p>
  396. <ol>
  397.   <li>Enter command-prompt and issue regsvr32 c:\easy.wsc</li>
  398.   <li> Locate it from Windows Explorer, right-click on the file and then choose 
  399.     "Register". </li>
  400. </ol>
  401. <BR>
  402. Either one of the above methods for registering a component should notify you upon success or
  403. failure. After registering the component, you can use it from within Active Server Pages by
  404. authoring a small script.<BR>
  405. <pre>
  406. <%@Language=PerlScript%>
  407. <%
  408.     $obj = $Server->CreateObject('Easy.WSC');
  409.     $retval = $obj->SayHello("Hello World");
  410.  
  411.     $Response->Write($retval);
  412. %>
  413. </pre>
  414. <br>
  415. <A name="comprop"></A>
  416. <H3>WSC with Properties and Notification</H3>
  417. Next, let's look at how to get a few properties included in the component, too. The following
  418. example will display how to read and write properties.It also includes comments, and, in addition, a
  419. custom subroutine is run when the component is registered and unregistered. What will happen is that
  420. when the component has been registered, a message box pops up with the text "Windows Script
  421. Component says: First.WSC has been registered!" and a similar tailored message when the
  422. component is unregistered by either oone of the ways previously shown. So, open up the Windows
  423. Script Component wizard, again, and this time enter the read/write property "YourName",
  424. and the method "SayHello." The property is a global variable, and it internally is read
  425. and written by subroutines that implement the functionality needed for performing the given
  426. operation. The property can either use "get" and "set" attributes that point to
  427. the mentioned subroutines or there can be separate "get" and "set" elements as
  428. in the example. Their values point to internal Perl subroutines that do their thing on the property.
  429. It is a simple example, and it is as follows.<BR>
  430. <pre>
  431. <?xml version="1.0"?>
  432. <component>
  433.     <registration
  434.         description="First"
  435.         progid="First.WSC"
  436.         version="1.00"
  437.         classid="{d0ccb637-bd0c-4c90-a4bd-7473f499d35a}"
  438.     >
  439.         <comment> 
  440.             This makes the messagebox pop up on registration and unregistation
  441.         </comment>
  442.         
  443.         <script language="PerlScript">
  444.             <![CDATA[
  445.             sub register { 
  446.                 use Win32;
  447.                 Win32::MsgBox('Windows Script Component says: First.WSC has been registered!');
  448.             }
  449.     
  450.             sub unregister { 
  451.                 use Win32;
  452.                 Win32::MsgBox('Windows Script Component says: First.WSC has been unregistered!');
  453.             }
  454.             ]]>
  455.         </script>
  456.     </registration>
  457.  
  458.     <comment> 
  459.         The methods and properties to expose to the data consumer 
  460.     </comment>
  461.  
  462.     <public> 
  463.         <property name="YourName">
  464.             <get internalName="hiddenGetProperty"/>
  465.             <put internalName="hiddenSetProperty"/>
  466.         </property>
  467.         <method name="SayHello">
  468.         </method>
  469.     </public>
  470.  
  471.     <comment> 
  472.         The code that implements the functionality of the component
  473.     </comment>
  474.  
  475.     <script language="PerlScript">
  476.         <![CDATA[
  477.         use vars qw($YourName_Property);
  478.  
  479.         sub hiddenGetProperty { 
  480.             return $YourName_Property;
  481.         }
  482.  
  483.         sub hiddenSetProperty { 
  484.             my($param) = shift;
  485.             $YourName_Property = $param;   
  486.         }
  487.  
  488.           sub SayHello { 
  489.             return "Hello $YourName_Property!";
  490.         }
  491.         ]]>
  492.     </script>
  493. </component>
  494. </pre>
  495. <BR>
  496. <A name="elementref"></A>
  497. <H2>XML Element Reference</H2>
  498. Windows Script Components use XML to mark up the definition of the component and 
  499. what is exposed by the component. Listed below are the elements that are valid 
  500. XML elements for use within WSC components..<br><A name="elemcom"></A> 
  501. <H3>The Component Element</H3>
  502. The component element is used to define the beginning and the end of the components. 
  503. It encapsulates all other WSC tags as illustrated.<BR>
  504. <BR>
  505. <pre>
  506.   <component>
  507.   .
  508.   .
  509.   .
  510.   </component>
  511. </pre>
  512. <br>
  513. <A name="elemcom"></A>
  514.  
  515.  You can also set a boolean value of true (1) or false (0) for error checking or debugging by using <CODE><? component error="true" debug="true" ?></CODE>
  516.  
  517.  In case your file will contain more than one component, you use a <CODE>&component id=componentID></CODE> element for each, and you are required to then enclose all components within a <CODE><package></CODE> element.
  518.  
  519.  
  520. <A name="elemcom"></A>
  521. <pre>
  522. <package>
  523.     <component id="ComponentA">
  524.      .
  525.      .
  526.      .
  527.      </component>
  528.  
  529.      <component id="ComponentB">
  530.      .
  531.      .
  532.      .
  533.      </component>
  534. </package>
  535. </pre>
  536. <BR>
  537. <BR>
  538. The default value for the component ID is ComponentCoClass, and when you define 
  539. your own, either to identify the components or for generating a typelibrary, the 
  540. name must be unique and it must begin with a letter and contain no spaces.<BR>
  541. <BR>
  542. When using more than one component within a package, you can create instances 
  543. of the other component within the current component by calling the <CODE>createComponent(componentID)</CODE> 
  544. function.<br> <A name="elemreg"></a>
  545. <H3>The Registration Element</H3>
  546. <CODE><registration></CODE> contains the necessary information in order 
  547. to successfully register the component as a COM component, and it has two ways 
  548. of writing. Syntax: <br>
  549. <pre>
  550. <registration
  551.     progid="progID"
  552.     classid="GUID"
  553.     description="description"
  554.     version="version"
  555.     [remotable=remoteFlag]
  556. />
  557. </pre>
  558. or <A name="elemreg"></a>
  559. <pre>
  560. <registration    
  561.     progid="progID"
  562.     classid="GUID"
  563.     description="description"
  564.     version="version"
  565.     [remotable=remoteFlag] 
  566. >
  567.  
  568.     <script>
  569.         (registration and unregistration script)
  570.     </script>
  571. </registration> 
  572. </pre>
  573. <BR>
  574. <BR>
  575. Most of the element attributes have been discussed in the introduction to the 
  576. COM. However, remotable, which is optional, specifies if the component can be 
  577. instantiated using DCOM. Its value can be true or false.<BR>
  578. <BR>
  579. <A name="elempub"></a>
  580. <H3>The Public Element</H3>
  581. The public element implements Automation, formerly known as OLE Automation, and 
  582. within the public elements you define the properties, methods, and events that 
  583. the component exposes after it has been registered. This is done using the property, 
  584. method, and event elements. 
  585. <pre>
  586. <public>
  587.     <property name="myProperty"/>
  588.     <method name="myMethod"/>
  589.     <event name="myEvent"/>  
  590. </public>
  591. </pre>
  592.  
  593. <A name="elemprop"></a>
  594. <H4>The Property Element</H4>
  595. Property declares a property exposed by the component. Syntax: 
  596. <UL>
  597.   <CODE><property name="myProperty" [internalName="propertyScalarVariable"] 
  598.   /></CODE> 
  599. </UL>
  600. <BR>
  601. The name of the property is what it will be exposed as, which needs to be the 
  602. same name as the global variable used to represent the proeprty. In contrast, 
  603. you can set an internalName attribute and run the property under another name 
  604. within the <script>-elements. You may also use the following syntax if you 
  605. wish to implement the properties as subroutines that calculate the value of the 
  606. property. or 
  607. <UL>
  608.   <CODE><property name="myProperty" get="getSubroutineNamet" 
  609.   put="putSubroutineName"/> </code>
  610. </UL>
  611. <BR>
  612. or<BR>
  613. <UL>
  614.   <pre><CODE><property name="myProperty">    </CODE></pre>
  615.   <CODE> 
  616.   <UL>
  617.     <pre><get [internalName="getSubroutineName"] />
  618.      <put [internalName="putSubroutineName"] />    </pre>
  619.   </UL>
  620.   </property></CODE> 
  621. </UL>
  622. <BR>
  623. Put indicates write-permissions while get indicated read-permissions. A combination 
  624. of the both as seen above indicated read/wrote permissons.<BR>
  625. <BR>
  626.  
  627. <pre><A name="elemmet">  </A></pre>
  628. <H4>The Method Element</H4>
  629. The method elements define the methods that are exposed by the component. Syntax: 
  630. <UL>
  631.   <CODE><method name="methodName" internalName="subroutineName" 
  632.   dispid=dispatchID /></CODE> 
  633. </UL>
  634. or<BR>
  635. <UL>
  636.   <pre><CODE><method    </CODE></pre>
  637.   <CODE>
  638.   <UL>
  639.     <pre>     name="methodName"
  640.      internalName="subroutineName"
  641.      dispid=dispatchID    </pre>
  642.   </UL>
  643.   > 
  644.   <UL>
  645.     <pre>     [<parameter name="param"/>]    </pre>
  646.   </UL>
  647.   </method></CODE> 
  648. </UL>
  649. <BR>
  650. The dispatchID is automatically generated unless you specify "0" as 
  651. a dispatchID, which will result in it being the default method of the component. 
  652. Parameter elements may belong to the method, if defined.<BR>
  653. <A name="elemmet"></a>
  654. <UL>
  655.   <CODE><parameter name="param"/></CODE> 
  656. </UL>
  657. <A name="elemevent"> </a> 
  658. <H4>The Event Element</H4>
  659. Declare an event that can be fired from within the component. Syntax:
  660. <UL>
  661.   <CODE><event name="name" dispid=dispatchID/></CODE>
  662. </UL>
  663. <BR>
  664. DispatchID is a numeric value that is generated automatically unless you specify it. From within
  665. your script, you use the <CODE>fireEvent(eventname);</CODE> method to execute an event.<BR>
  666. <BR>
  667. <A name="elemimp"></A>
  668. <H3>The Implements Element</H3>
  669. The Implements element enables you to include more COM interface handlers within your script.
  670. Syntax:
  671. <UL>
  672.   <pre><CODE><implements   
  673. </CODE>     type="COMHandlerName"
  674.      [id="internalName"]
  675.      [default=fAssumed]   </pre>
  676.   <CODE>><BR>
  677.   Information related to the COMHandler goes here<BR>
  678.   </implements></CODE> 
  679. </UL>
  680. <BR>
  681. COMHandlerName is the name of an interface handler that you wish to implement, 
  682. and internalName is the name to which you want to reference the COMHandler. This 
  683. is useful to avoid naming conflicts because the components exposed data is available 
  684. in the global namespace. The fAssumed flag is a boolean values used to define 
  685. if internalName is assumed in scripts, which is the default setting..<BR>
  686. <BR>
  687. The Windows Script Components run-time (scrobj.dll) implement handlers for Automation 
  688. and ASP, and also handlers for accesing the DHTML object model in the page. <A name="elemimp"></a>
  689. <UL>
  690.   <pre><CODE>
  691.    <component>
  692.    <registration progid="SimpleASP.WSC"/>
  693.    
  694.    <public>    </CODE></pre>
  695.   <CODE>
  696.   <UL>
  697.     <pre><method name="TestWrite"/>    </pre>
  698.   </UL>
  699.   </public><BR>
  700.   <BR>
  701.   <implements type="ASP"/><BR>
  702.   <script language="PerlScript"><BR>
  703.   <![CDATA[<BR>
  704.   sub TestWrite { 
  705.   <UL>
  706.     <pre>     Response.Write("Hello World, says ASP!")    </pre>
  707.   </UL>
  708.   }<BR>
  709.   ]]><BR>
  710.   </script><BR>
  711.   </component></CODE> 
  712. </UL>
  713.  
  714. <pre><A name="elemscr">  </A></pre>
  715. <H3>The Script Element</H3>
  716. The script element lets you define the scripting language to use, and then with 
  717. its closing-tag functions as delimiters for the script code. Syntax: 
  718. <UL>
  719.   <CODE><script language="languageName"> code </script></CODE> 
  720. </UL>
  721. For example. 
  722. <UL>
  723.   <CODE><BR>
  724.   <?XML version="1.0"?><BR>
  725.   <component><BR>
  726.   ...<BR>
  727.   <script language="PerlScriptt"><BR>
  728.   <![CDATA[<BR>
  729.   sub ReturnValue {<BR>
  730.   #<BR>
  731.   # Perl code here<BR>
  732.   #<BR>
  733.   }<BR>
  734.   ]]><BR>
  735.   </script><BR>
  736.   </component> </code>
  737. </UL>
  738. <A name="elemobj"> </A> 
  739. <H3>The Object Element</H3>
  740. The object element enables you to create an instance of a COM object that you want to use within
  741. your Windows Script Component Syntax:
  742. <UL>
  743.   <pre><CODE><object id="objectID"   </code></pre>
  744.   <CODE>
  745.   <UL>
  746.     <pre>     [classid="classid:GUID" | progid="progID"]   </pre>
  747.   </UL>
  748.   /> </code>
  749. </UL>
  750. The objectID is the name by which you want to reference the object within your 
  751. script, and you can use either the progID or classID to locate the component. 
  752. For example, how to create an instance using the COM components progID: <A name="elemobj"> </a>
  753. <UL>
  754.   <pre><CODE>
  755.    <?XML version="1.0"?>
  756.    <component>
  757.    <object id="conn" progid="ADODB.Connection.2.5">
  758.    <script language="PerlScript">
  759.    <![CDATA[
  760.    sub OpenConn {    </code></pre>
  761.   <CODE>
  762.   <UL>
  763.     <pre>     my($status);
  764.      
  765.      $conn->Open(<<EOF);
  766.      Provider=SQLOLEDB;
  767.      Persist Security Info=False;
  768.      User ID=sa;
  769.      Initial Catalog=Northwind
  770.      EOF
  771.      
  772.      if($conn->{State} == adStateOpen) {
  773.      $status = "Connection was a success";
  774.      }
  775.      else {
  776.      $status = "Connection failed because ";
  777.      $status .= $conn->Errors(0)->{Description};
  778.      }
  779.      
  780.      $conn->Close();
  781.      
  782.      return $status;    </pre>
  783.   </UL>
  784.   }<BR>
  785.   <BR>
  786.   ]]><BR>
  787.   </script><BR>
  788.   </component> </code> 
  789. </UL>
  790. <pre><A name="elemres">  </A></pre>
  791. <H3>The Resource Element</H3>
  792. The resource element is a placeholder for strings or numeric data that should 
  793. be separate from the script commands yet may be used within the script. Syntax: 
  794. <UL>
  795.   <pre><CODE><resource id="resourceID">    </code></pre>
  796.   <CODE>
  797.   <UL>
  798.     <pre>     text or number to represent resource goes here    </pre>
  799.   </UL>
  800.   </resource> </code> 
  801. </UL>
  802. You use the <CODE>getResource(resourceID)</CODE> to retrieve the contents of the 
  803. resource specified in the resourceID parameter.<BR>
  804. <BR>
  805. <pre><A name="elemref">  </A></pre>
  806. <H3>The Reference Element</H3>
  807. You can import external type libraries into your component by using the reference 
  808. element. By importing a type library into your component, you will be able to 
  809. naturally access the constants that belongs to it, too. Syntax: 
  810. <UL>
  811.   <pre><CODE><reference    </code></pre>
  812.   <CODE>
  813.   <UL>
  814.     <pre>     [object="progID"|guid="typelibGUID"]
  815.      [version="versionNo"]    </pre>
  816.   </UL>
  817.   /> </code> 
  818. </UL>
  819. For example, you can use an ActiveX Data Object within your component. <A name="elemref"></a> 
  820. <UL>
  821.   <pre><CODE>
  822.    <?XML version="1.0"?>
  823.    <component>
  824.    <reference object="ADODB.Connection.2.5"/>
  825.    <registration progid="SimpleADO.WSC"/>
  826.    <public>
  827.    <method name="OpenConn"/>
  828.    </public>
  829.    
  830.    <script language="PerlScript">
  831.    <![CDATA[
  832.    sub OpenConn {    </code></pre>
  833.   <CODE>
  834.   <UL>
  835.     <pre>     my($status);
  836.      
  837.      $conn = new Win32::OLE("ADODB.Connection");
  838.      $conn->Open(<<EOF);
  839.      Provider=SQLOLEDB;
  840.      Persist Security Info=False;
  841.      User ID=sa;
  842.      Initial Catalog=Northwind
  843.      EOF
  844.      
  845.      if($conn->{State} == adStateOpen) {
  846.      $status = "Connection was a success";
  847.      }
  848.      else {
  849.      $status = "Connection failed because ";
  850.      $status .= $conn->Errors(0)->{Description};
  851.      }
  852.      
  853.      $conn->Close();
  854.      
  855.      return $status;    </pre>
  856.   </UL>
  857.   }<BR>
  858.   <BR>
  859.   ]]><BR>
  860.   </script><BR>
  861.   </component> </code> 
  862. </UL>
  863. <pre><A name="elemcomment"></A>  </pre>
  864. <H3>The Comment Element</H3>
  865. The Comment element encloses descriptive strings that are used to describe the on-goings in the code
  866. and the strings are ignored by the language parser when preparing the code to execute.
  867. <UL>
  868.   <pre><CODE><comment>   </code></pre>
  869.   <CODE> 
  870.   <UL>
  871.     <pre>     Author: John Doe
  872.      Description: This WSC component is used to output a Binary Large Object (BLOB) from an SQL     Server database . . .   </pre>
  873.   </UL>
  874.   </comment></code>
  875. </UL>
  876. <HR>
  877. <H1><A name="author and copyright">AUTHOR AND COPYRIGHT</A></H1>
  878. <P>Copyright (c) 2000 Tobias Martinsson. All Rights Reserved.</P>
  879. <P>When included as part of the Standard Version of Perl, or as part of its complete documentation
  880. whether printed or otherwise, this work may be distributed only under the terms of Perl's Artistic
  881. License. Any distribution of this file or derivatives thereof <EM>outside</EM> of that package
  882. require that special arrangements be made with copyright holder.</P>
  883. <P>Irrespective of its distribution, all code examples in this file are hereby placed into the
  884. public domain. You are permitted and encouraged to use this code in your own programs for fun or for
  885. profit as you see fit. A simple comment in the code giving credit would be courteous but is not
  886. required.</P>
  887. <P>Windows Script Components is copyright (c) 1991-1999 Microsoft Corporation. All rights reserved.</P>
  888. <TABLE border="0" cellpadding="0" cellspacing="0" width="100%">
  889.   <TR>
  890.     <TD class="block" valign="MIDDLE" width="100%" bgcolor="#cccccc"><STRONG>
  891.       <P class="block"> Windows Script Components</P>
  892.       </STRONG></TD>
  893.   </TR>
  894. </TABLE>
  895.  
  896. </BODY>
  897.  
  898. </HTML>
  899.