Helix SwarmHelix Swarm

GettingStarted.html

  • //
  • guest/
  • erik_purins/
  • P4.Net/
  • release/
  • 0.9/
  • doc/
  • html/
  • GettingStarted.html #1
  • View
  • Commits
  • Open Download .zip Download (12 KB)
  1. <html xmlns="http://www.w3.org/1999/xhtml">
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252" />
  4. <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5" />
  5. <title>P4.Net: Getting Started</title>
  6. <link rel="stylesheet" type="text/css" href="MSDN.css" />
  7. </head>
  8. <body id="bodyID" class="dtBODY">
  9. <div id="nsbanner">
  10. <div id="bannerrow1">
  11. <table class="bannerparthead" cellspacing="0" id="Table1">
  12. <tr id="hdr">
  13. <td class="runninghead">
  14. Perforce API for the .Net CLR</td>
  15. <td class="product">
  16. <img alt="P4.Net" src="p4net.GIF" /></td>
  17. </tr>
  18. </table>
  19. </div>
  20. <div id="TitleRow">
  21. <h1 class="dtH1">
  22. Getting Started</h1>
  23. </div>
  24. </div>
  25. <div id="nstext">
  26. <h4 class="dtH4">
  27. Connecting to the Server</h4>
  28. <p>
  29. The P4Connection class is the main player in P4.Net. This represents a connection
  30. to the Perforce server. Every utility that uses P4.Net will have some variation
  31. of the following code:
  32. </p>
  33. <pre class="code" language="C#" escaped="true">
  34. P4Connection p4 = new P4Connection();
  35. p4.Connect();
  36.  
  37. // Run some commands
  38. p4.Disconnect();</pre>
  39. <p>
  40. Rule number 1: Always remember to disconnect. This frees unmanaged memory, and cleanly
  41. disconnects from the Perforce server. P4Connection implements IDisposable, and the
  42. Dispose and Disconnect methods can be used interchangeably.
  43. </p>
  44. <p>
  45. P4.Net is based off the command-line syntax (as are most other Perforce APIs). Almost
  46. all of the commands you issue in P4.Net will use the same arguments as the p4 client
  47. executable. For example, say you need to find the latest submitted changelist under
  48. a given path (//depot/path). From the command line:</p>
  49. <pre class="code" escaped="true">
  50. c:\> p4 changes -m1 -s submitted //depot/path/...</pre>
  51. <p>
  52. From P4.Net:</p>
  53. <pre class="code" language="C#" escaped="true">
  54. P4Connect p4 = new P4Connection();
  55. p4.Connect();
  56. P4Recordset changes = p4.Run("changes", "-m1", "-s", "submitted", "//depot/path/...");
  57. p4.Disconnect();</pre>
  58. <p>
  59. If you dont know what all the arguments for p4 changes mean, then p4 help changes
  60. is your best friend. The first step in building anything with P4.Net, is to know
  61. the exact command lines youd run manually.
  62. </p>
  63. <h4 class="dtH4">
  64. Interpreting Output</h4>
  65. <p>
  66. Although the arguments to run Perforce commands are similar to the command line
  67. interface, the way we interpret the output can be dramatically different. This is
  68. where the power of the API comes in. In the example above, the result changes is
  69. of type P4Recordset. This is a rich object in P4.Net that provides a parsed version
  70. of the command output. At the core of the P4Recordset is the enumerable collection
  71. of P4Records. Each P4Record generally represents all the data on one lines output
  72. from the command-line. P4Records are dictionary-like objects allowing you to access
  73. fields by a key:</p>
  74. <pre class="code" language="C#" escaped="true">
  75. // we used the -m1 switch, so we know there is just one record returned.
  76. P4Record change = changes[0];
  77. int changeNumber = int(change["change"]);</pre>
  78. <p>
  79. It can also be accessed using the Fields property:
  80. </p>
  81. <pre class="code" language="C#" escaped="true">
  82. int changeNumber = int(change.Fields["change"]);</pre>
  83. <p>
  84. So, how do you know what keys are available? Well, it depends on the command run,
  85. the server version, and sometimes the arguments to the command. The RecordsetViewer
  86. sample application is a great tool for determining the keys that are returned from
  87. a command. In addition to RecordsetViewer, you can use the -Ztag global option of
  88. the p4 command line client to see how the output is parsed. At runtime, you can
  89. access all of the keys returned from the Fields.Keys property:
  90. </p>
  91. <pre class="code" language="C#" escaped="true">
  92. foreach (string key in change.Fields.Keys)
  93. {
  94. Console.WriteLine("{0} : {1}", key, change[key]);
  95. }</pre>
  96. <p>
  97. In addition to the normal parsed output, there may be warnings, errors, and informational
  98. messages from the command that are not parsed (i.e. it will be the same English
  99. message returned at the command line). Again, the RecordsetViewer sample application
  100. can help you identify all the elements returned in a P4Recordset for a particular
  101. command. At runtime, we can access those messages as shown below:
  102. </p>
  103. <pre class="code" language="C#" escaped="true">
  104. foreach (string e in changes.Errors) Console.WriteLine(e);
  105. foreach (string e in changes.Warnings) Console.WriteLine(e);
  106. foreach (string e in changes.Messages) Console.WriteLine(e);</pre>
  107. <p>
  108. Not all fields have a single string for a value. Some commands return arrays of
  109. strings in a field. To access these values at runtime, you can use the ArrayFields
  110. property of the P4Record object.
  111. </p>
  112. <pre class="code" language="C#" escaped="true">
  113. P4Recordset describes = p4.Run("describe", "-s", "1234");
  114.  
  115. //One changelist, one record... at least if that changelist exists
  116. P4Record describe = describes[0];
  117.  
  118. Console.WriteLine("Changelist: {0}", describe["Change"]);
  119.  
  120. Console.WriteLine("Files:");
  121.  
  122. foreach( int i=0; i< describe.ArrayFields["depotFile"].Length; i++)
  123. {
  124. Console.WriteLine(" {0}#{1}", describe.ArrayFields["depotFile"][i], describe.ArrayFields["rev"][i]);
  125. }</pre>
  126. <p>
  127. In the preceding examples, we only looked at the first record in the recordset.
  128. However many commands will return multiple records. We can enumerate them as follows:
  129. </p>
  130. <pre class="code" language="C#" escaped="true">
  131. // This example enumerates all the files in a folder hierarchy, and prints the ones
  132. // that are deleted at the head revision. (Note, theres a more efficient way to do this.)
  133. P4Recordset fstats = p4.Run("fstat", "//depot/path/...");
  134. foreach( P4Record stat in fstats)
  135. {
  136. if (stat["headAction"] == "delete")
  137. {
  138. Console.WriteLine(stat["depotFile"]);
  139. }
  140. }</pre>
  141. <h4 class="dtH4">
  142. Unparsed Output</h4>
  143. <p>
  144. Not all commands support the parsed output. In that case, all of the output will
  145. be simple English statements, just as the command line outputs. Again, this is highly
  146. dependent on the version of the Perforce server. You can see the Perforce C++ API
  147. release notes for your version to see if the parsed output is supported for a given
  148. command (referred to as tagged in the C++ documentation).
  149. </p>
  150. <p>
  151. While you can access these messages from the P4Recordset.Messages property, its
  152. often easier to use the RunUnParsed method of the P4Connection class, which returns
  153. a P4UnParsedRecordset object. This is similar to the P4Recordset object, except
  154. there are no Fields and ArrayFields properties, and the default enumerator is the
  155. Messages array.
  156. </p>
  157. <p>
  158. RunUnParsed can also help ensure forward compatibility with newer server versions.
  159. In recent releases, many commands that previously only supported the unparsed output,
  160. now support parsed output. If the server is upgraded, code that called Run, would
  161. still look at the P4Recordset.Messages. However the output from the upgraded server
  162. would now be available only in Fields and ArrayFields. By using RunUnParsed, you
  163. are guaranteed to get the raw strings from the server.
  164. </p>
  165. <p />
  166. <h4 class="dtH4">
  167. Forms</h4>
  168. <p>
  169. Another major object in P4.Net is the P4Form object. Perforce forms are the text
  170. files that pop up in an editor when a "form" command is run. They have fields that
  171. are specially formatted in the file, and you can view or change these fields by
  172. following the formatting standards. You can see this behavior in the command line:
  173. </p>
  174. <pre class="code" escaped="true">
  175. c:\> p4 user</pre>
  176. <p>
  177. In P4.Net, you do not have to worry about this special formatting. The fields are
  178. read/modified using Fields and ArrayFields properties (P4Form inherits P4Record).
  179. The only trick is you need to use the methods Fetch_Form and Save_Form:</p>
  180. <pre class="code" language="C#" escaped="true">
  181. // Change the root of the current workspace.
  182. P4Connection p4 = new P4Connection();
  183. p4.Connect();
  184. P4Form client = p4.Fetch_Form("client");
  185. client["Root"] = @"c:\p4";
  186. p4.Save_Form(client);
  187. p4.Disconnect();</pre>
  188. <p />
  189. <p />
  190. <h4 class="dtH4">
  191. Submitting Files</h4>
  192. <p>
  193. In P4.Net, theres no straight-forward way to submit the default pending changelist.
  194. This is by design. If the client workspace has opened files in the default changelist
  195. before any P4.Net automation runs, those files will "come along for the ride" when
  196. you submit the default changelist. If the user has a JobView set, all jobs in that
  197. JobView will automatically be fixed when you submit the default changelist. Both
  198. of those behaviors are almost never desired, and Ive found many scripts that have
  199. those bugs.
  200. </p>
  201. <p>
  202. So, how do you submit files in P4.Net? The key is to create a named pending changelist
  203. before opening any files. Then add the switches "-c", and "1234" (1234 is the changelist
  204. number) to all commands that are opening files. This is quite simple using the P4PendingChangelist
  205. object:
  206. </p>
  207. <pre class="code" language="C#" escaped="true">
  208. P4Connection p4 = new P4Connection();
  209. p4.Connect();
  210. P4PendingChangelist cl = p4.CreatePendingChangelist("My New Changelist\nVery, Very bad description!\nShame on me!");
  211. p4.Run("edit", "-c", cl.Number.ToString(), "//depot/path/foo.cs", "//depot/path/bar.cs");
  212. // Do something to manipulate the files
  213. cl.Submit();
  214. p4.Disconnect();</pre>
  215. <h4 class="dtH4">
  216. Connections Revisited.</h4>
  217. <p>
  218. Finally, lets look at the connection properties. You may be wondering how the P4Connection
  219. object knows which Port/Client/User to use. It turns out P4.Net will use the default
  220. properties using the same logic as all Perforce clients (see Technote 36 and the
  221. P4 User Guide). Of course, any of these can be explicitly overridden on the P4Connection
  222. object. However, Ive found using the built-in Perforce configuration system to
  223. be much more portable and maintainable than explicitly defining the configuration
  224. for each custom tool.
  225. </p>
  226.  
  227. <hr />
  228. <div id="footer">
  229. <p>
  230. <a href="Copyright.html">Copyright 2006 Shawn Hladky</a>
  231. </p>
  232. <p>
  233. </p>
  234. </div>
  235. </div>
  236. </body>
  237. </html>
# Change User Description Committed
#1 7341 Erik Purins p4.net
---
pull p4.net#head
16 years ago
//guest/shawn_hladky/P4.Net/release/0.9/doc/html/GettingStarted.html
#1 5831 Shawn Hladky P4.Net: Branch release 0.9 and delete a few files missed last time 19 years ago
//guest/shawn_hladky/P4.Net/main/doc/html/GettingStarted.html
#1 5830 Shawn Hladky P4.Net: reorg to support release branches 19 years ago
//guest/shawn_hladky/P4.Net/doc/html/GettingStarted.html
#2 5825 Shawn Hladky P4.Net: Binaries and compiled docs for 0.9 19 years ago
#1 5812 Shawn Hladky P4.Net: More documentation. 19 years ago