The retrieve call is just the opposite of the deploy call. With the retrieve call we receive the list of files that are requested and information about those files. The files come back in a zip file that matches the structure that you would see in your Eclipse projects.
Here is the source code I was using to test the retrieve call. Please see the comments in the code for details about specific sections.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
Private Sub DoRetrieve() Dim newRetrieveResult As SFMetadataAPI.RetrieveResult Dim asyncResultItem As New SFMetadataAPI.AsyncResult Dim newRetrieveRequest As New SFMetadataAPI.RetrieveRequest //The Package object is very important. This tell the Retrieve() call what files to pull down. Dim myPackage As New SFMetadataAPI.Package //The PackageTypeMembers are the members of the package that should be retrieved. Dim myPackageMembers(0 To 25) As SFMetadataAPI.PackageTypeMembers Dim myPackageMemberItem As New SFMetadataAPI.PackageTypeMembers Dim fileNameForRetrievedZip As String Dim extractedFolder As String Dim myFiles(0 To 0) As String Dim myFilesForStandardObjects(0 To 25) As String Dim packagesToDownload(0 To 0) As String Dim asyncProcIDArray(0 To 0) As String Dim metaDataTypes As New ArrayList Dim newFiles As ArrayList Dim i As Integer newRetrieveRequest.apiVersion = 26 If False Then 'Use Package that is already setup in the Salesforce Org newRetrieveRequest.specificFiles = Nothing newRetrieveRequest.singlePackage = True packagesToDownload(0) = "MetaDataTest" 'This is a test package I created in my Salesforce Org for testing newRetrieveRequest.packageNames = packagesToDownload Else 'Individual Files using a package structure newRetrieveRequest.specificFiles = Nothing newRetrieveRequest.singlePackage = True newRetrieveRequest.packageNames = Nothing 'Create the package structure myPackage.fullName = "pullPackage" //Set the API version. We could place this in the app.config file so that it is not hard-coded myPackage.version = "26.0" //Add each of the metadata API types that we want to retrieve metaDataTypes.Add("ApexClass") metaDataTypes.Add("ApexComponent") metaDataTypes.Add("ApexPage") metaDataTypes.Add("ApexTrigger") metaDataTypes.Add("CustomLabels") metaDataTypes.Add("CustomApplication") metaDataTypes.Add("CustomObject") metaDataTypes.Add("CustomObjectTranslation") metaDataTypes.Add("CustomPageWebLink") metaDataTypes.Add("CustomSite") metaDataTypes.Add("CustomTab") metaDataTypes.Add("Dashboard") metaDataTypes.Add("DataCategoryGroup") metaDataTypes.Add("HomePageComponent") metaDataTypes.Add("HomePageLayout") metaDataTypes.Add("Layout") metaDataTypes.Add("Letterhead") metaDataTypes.Add("PermissionSet") metaDataTypes.Add("Profile") metaDataTypes.Add("RemoteSiteSetting") metaDataTypes.Add("Report") metaDataTypes.Add("ReportType") metaDataTypes.Add("Scontrol") metaDataTypes.Add("StaticResource") metaDataTypes.Add("Translations") metaDataTypes.Add("Workflow") myFiles(0) = "*" '* will bring back all files 'If you want just one file you can specify that "startHereController" myFilesForStandardObjects(0) = "*" myFilesForStandardObjects(1) = "Account" myFilesForStandardObjects(2) = "AccountContactRole" myFilesForStandardObjects(3) = "Activity" myFilesForStandardObjects(4) = "Asset" myFilesForStandardObjects(5) = "Campaign" myFilesForStandardObjects(6) = "CampaignMember" myFilesForStandardObjects(7) = "Case" myFilesForStandardObjects(8) = "CaseContactRole" myFilesForStandardObjects(9) = "Contact" myFilesForStandardObjects(10) = "ContentVersion" myFilesForStandardObjects(11) = "Contract" myFilesForStandardObjects(12) = "ContractContactRole" myFilesForStandardObjects(13) = "Event" myFilesForStandardObjects(14) = "Idea" //The JigsawSavedSearch did not seem to want to be retrieved yet. 'myFilesForStandardObjects(15) = "JigsawSavedSearch" myFilesForStandardObjects(15) = "Lead" myFilesForStandardObjects(16) = "Opportunity" myFilesForStandardObjects(17) = "OpportunityContactRole" myFilesForStandardObjects(18) = "OpportunityLineItem" myFilesForStandardObjects(19) = "PartnerRole" myFilesForStandardObjects(20) = "Product2" myFilesForStandardObjects(21) = "Site" myFilesForStandardObjects(22) = "Solution" myFilesForStandardObjects(23) = "Task" myFilesForStandardObjects(24) = "User" myFilesForStandardObjects(25) = "UserLicense" 'Metadata Name Location For i = 0 To 25 //Create PackageTypeMembers one by one and place them in the myPackageMembers array myPackageMemberItem = New SFMetadataAPI.PackageTypeMembers myPackageMemberItem.name = metaDataTypes(i) If myPackageMemberItem.name = "CustomObject" Then myPackageMemberItem.members = myFilesForStandardObjects Else myPackageMemberItem.members = myFiles End If myPackageMembers(i) = myPackageMemberItem Next myPackage.types = myPackageMembers newRetrieveRequest.unpackaged = myPackage End If //Now that our package is built we can call the retrieve call on the Metadata API asyncResultItem = sfMetaData.retrieve(newRetrieveRequest) //The done property will tell us if the retrieve call is complete. If (asyncResultItem.done = False) Then //The waitUntilDone will use the id value returned from the original retrieve call. Then Salesforce knows which retrieve call we are asking about for its status. waitUntilDone(asyncResultItem.id) End If //Now that the retrieve call is fully done we call checkRetrieveStatus to get the actual results of the retrieve call newRetrieveResult = sfMetaData.checkRetrieveStatus(asyncResultItem.id) If newRetrieveResult.messages Is Nothing Then //If messages are not nothing then we have returned some data fileNameForRetrievedZip = "C:\Users\terry.luschen\Documents\Salesforce Info\DeployTest3\Retrieve.zip" extractedFolder = "C:\Users\terry.luschen\Documents\Salesforce Info\DeployTest3\" //Delete the destination folder if it already exists to remove it and all sub-directories and files. If System.IO.Directory.Exists(extractedFolder) Then System.IO.Directory.Delete(extractedFolder, True) End If //Do some minor thread waiting so the file and directory changes have time to complete. Threading.Thread.Sleep(500) System.IO.Directory.CreateDirectory(extractedFolder) Threading.Thread.Sleep(500) //The zip file that has been downloaded because of the retrieve() call is simply a property called 'zipFile' on the result object. System.IO.File.WriteAllBytes(fileNameForRetrievedZip, newRetrieveResult.zipFile()) 'This is the zip file utility being used to extract the files. The dll is called Ionic.Zip.dll Using zip As Ionic.Zip.ZipFile = Ionic.Zip.ZipFile.Read(fileNameForRetrievedZip) zip.ExtractAll("C:\Users\terry.luschen\Documents\Salesforce Info\DeployTest3\") End Using //We now have a folder that has all of the files that we wanted to retrieve. The example here is basically requesting most of the // metadata API objects. This could make the retrieve rather slow if it is a large org. End If End SubPrivate Sub waitUntilDone(ByVal idValue As String) Dim asyncResultItems() As SFMetadataAPI.AsyncResult Dim asyncProcIDArray(0 To 0) As String asyncProcIDArray(0) = idValue Do Threading.Thread.Sleep(500) //The checkstatus call will ask Salesforce if the retrieve job requested has been completed or not. asyncResultItems = sfMetaData.checkStatus(asyncProcIDArray) Loop While asyncResultItems(0).done = FalseEnd Sub |
I hope that this code gives you a head start when you need to create some custom code to interact with the Metadata API. It is a very powerful API and I think developers will continue to build more and more utilities around the metadata API to make our lives easier.
If there are other parts of the Metadata API that you would like me to explore please let me know.


