home *** CD-ROM | disk | FTP | other *** search
/ Netrunner 2004 October / NETRUNNER0410.ISO / regular / ActivePerl-5.8.4.810-MSWin32-x86.msi / _18233f643da441fd61f68e612d8c3749 < prev    next >
Encoding:
Text File  |  2004-06-01  |  42.5 KB  |  927 lines

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