Skip to content
View on GitHubSample viewer app

Demonstrates how to start and stop the Local Server and start and stop a local map, feature, and geoprocessing service running on the Local Server.

Image of local server services

Use case

For executing offline geoprocessing tasks in your apps via an offline (local) server.

How to use the sample

Click Start Local Server to start the Local Server. Click Stop Local Server to stop the Local Server.

The Map Service control lets you to pick a local service that is available.

After browsing for the desired file, click Start Service to start the selected service.

When the running service's url appears, select it and click Navigate to service. To stop this running service, click Stop Service.

How it works

To start a LocalServer and attach a LocalService:

  1. Create and run a local server with LocalServer.Instance.
  2. Start the server asynchronously with server.StartAsync().
  3. Create and run a local service. Here is an example of running a LocalMapService:
    1. Instantiate LocalMapService(Url) to create a local map service with the given URL path to map package (mpk or mpkx file).
    2. Start the job with LocalMapService.StartAsync(). The service is added to the LocalServer automatically.
  4. Stop the local server with LocalServer.Instance.StopAsync().

Relevant API

  • LocalFeatureService
  • LocalGeoprocessingService
  • LocalMapService
  • LocalServer
  • LocalServerStatus
  • LocalService

Offline data

Additional information

ArcGIS Maps SDK for Local Server (Local Server) is deprecated and will be retired in 2030. The last release will be ArcGIS Maps SDK for Local Server 200.8, in Q3 2025. For more information, see the deprecation announcement.

Tags

feature, geoprocessing, local services, map, server, service

Sample Code

LocalServerServices.xaml.csLocalServerServices.xaml.csLocalServerServices.xaml
Use dark colors for code blocksCopy
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 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 // Copyright 2021 Esri. // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. // You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific // language governing permissions and limitations under the License.  using ArcGIS.Samples.Managers; using Esri.ArcGISRuntime.LocalServices; using System; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Windows; using System.Windows.Controls;  namespace ArcGIS.WPF.Samples.LocalServerServices {  [ArcGIS.Samples.Shared.Attributes.Sample(  name: "Local server services",  category: "Local Server",  description: "Demonstrates how to start and stop the Local Server and start and stop a local map, feature, and geoprocessing service running on the Local Server.",  instructions: "Click `Start Local Server` to start the Local Server. Click `Stop Local Server` to stop the Local Server.",  tags: new[] { "feature", "geoprocessing", "local services", "map", "server", "service" })]  [ArcGIS.Samples.Shared.Attributes.OfflineData("85c34847bbe1402fa115a1b9b87561ce", "92ca5cdb3ff1461384bf80dc008e297b", "a680362d6a7447e8afe2b1eb85fcde30")]  public partial class LocalServerServices  {  // Hold references to the individual services  private LocalMapService _localMapService;  private LocalFeatureService _localFeatureService;  private LocalGeoprocessingService _localGeoprocessingService;   // Generic reference to the service selected in the UI  private LocalService _selectedService;   public LocalServerServices()  {  InitializeComponent();   // Set up the sample  Initialize();  }   private void Initialize()  {  try  {  // Subscribe to event notification for the local server instance  LocalServer.Instance.StatusChanged += (o, e) =>  {  UpdateUiWithServiceUpdate("Local Server", e.Status);  };  }  catch (Exception ex)  {  var localServerTypeInfo = typeof(LocalMapService).GetTypeInfo();  var localServerVersion = FileVersionInfo.GetVersionInfo(localServerTypeInfo.Assembly.Location);   MessageBox.Show($"Please ensure that local server {localServerVersion.FileVersion} is installed prior to using the sample. The download link is in the description. Message: {ex.Message}", "Local Server failed to start");  }  }   private void UpdateUiWithServiceUpdate(string server, LocalServerStatus status)  {  // Construct the new status text  string updateStatus = String.Format("{0} status: {1} \t\t {2}\n{3}", server, status,  DateTime.Now.ToShortTimeString(), StatusTextbox.Text);   // Update the status box text  StatusTextbox.Text = updateStatus;   // Update the list of running services  ServicesListbox.ItemsSource = LocalServer.Instance.Services.Select(m => m.Name + " : " + m.Url);  }   private void CreateServices()  {  try  {  // Arrange the data before starting the services  string mapServicePath = GetMpkPath();  string featureServicePath = GetFeatureLayerPath();  string geoprocessingPath = GetGpPath();   // Create each service but don't start any  _localMapService = new LocalMapService(mapServicePath);  _localFeatureService = new LocalFeatureService(featureServicePath);  _localGeoprocessingService = new LocalGeoprocessingService(geoprocessingPath);   // Subscribe to status updates for each service  _localMapService.StatusChanged += (o, e) => { UpdateUiWithServiceUpdate("Map Service", e.Status); };  _localFeatureService.StatusChanged += (o, e) => { UpdateUiWithServiceUpdate("Feature Service", e.Status); };  _localGeoprocessingService.StatusChanged += (o, e) => { UpdateUiWithServiceUpdate("Geoprocessing Service", e.Status); };   // Enable the UI to select services  ServiceSelectionCombo.IsEnabled = true;  }  catch (Exception ex)  {  MessageBox.Show(ex.Message, "Failed to create services");  }  }   private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)  {  // Get the text of the selected item  string selection = ((ComboBoxItem)ServiceSelectionCombo.SelectedItem).Content.ToString();   // Update the selection  switch (selection)  {  case "Map Service":  _selectedService = _localMapService;  break;   case "Feature Service":  _selectedService = _localFeatureService;  break;   case "Geoprocessing Service":  _selectedService = _localGeoprocessingService;  break;  }   // Return if selection is invalid  if (_selectedService == null)  {  return;  }   // Update the state of the start and stop buttons  UpdateServiceControlUi();  }   private void UpdateServiceControlUi()  {  if (_selectedService == null)  {  return;  }   // Update the UI  if (_selectedService.Status == LocalServerStatus.Started)  {  ServiceStopButton.IsEnabled = true;  ServiceStartButton.IsEnabled = false;  }  else  {  ServiceStopButton.IsEnabled = false;  ServiceStartButton.IsEnabled = true;  }  }   private async void StartServiceButtonClicked(object sender, RoutedEventArgs e)  {  try  {  // Start the selected service  await _selectedService.StartAsync();   // Update the UI  UpdateServiceControlUi();  }  catch (Exception ex)  {  MessageBox.Show(ex.Message, "Failed to start service");  }  }   private async void StopServiceButtonClicked(object sender, RoutedEventArgs e)  {  try  {  // Stop the selected service  await _selectedService.StopAsync();   // Update the UI  UpdateServiceControlUi();  }  catch (Exception ex)  {  MessageBox.Show(ex.Message, "Failed to stop service");  }  }   private static string GetMpkPath()  {  return DataManager.GetDataFolder("85c34847bbe1402fa115a1b9b87561ce", "RelationshipID.mpkx");  }   private static string GetFeatureLayerPath()  {  return DataManager.GetDataFolder("92ca5cdb3ff1461384bf80dc008e297b", "PointsOfInterest.mpkx");  }   private static string GetGpPath()  {  return DataManager.GetDataFolder("a680362d6a7447e8afe2b1eb85fcde30", "Contour.gpkx");  }   private async void StartServerButtonClicked(object sender, RoutedEventArgs e)  {  try  {  // LocalServer must not be running when setting the data path.  if (LocalServer.Instance.Status == LocalServerStatus.Started)  {  await LocalServer.Instance.StopAsync();  }   // Set the local data path - must be done before starting. On most systems, this will be C:\EsriSamples\AppData.  // This path should be kept short to avoid Windows path length limitations.  string tempDataPathRoot = Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.Windows)).FullName;  string tempDataPath = Path.Combine(tempDataPathRoot, "EsriSamples", "AppData");  Directory.CreateDirectory(tempDataPath); // CreateDirectory won't overwrite if it already exists.  LocalServer.Instance.AppDataPath = tempDataPath;   // Start the server  await LocalServer.Instance.StartAsync();   // Create the services  CreateServices();  }  catch (Exception ex)  {  var localServerTypeInfo = typeof(LocalMapService).GetTypeInfo();  var localServerVersion = FileVersionInfo.GetVersionInfo(localServerTypeInfo.Assembly.Location);   MessageBox.Show($"Please ensure that local server {localServerVersion.FileVersion} is installed prior to using the sample. The download link is in the description. Message: {ex.Message}", "Local Server failed to start");  }   // Update the UI  LocalServerStopButton.IsEnabled = true;  LocalServerStartButton.IsEnabled = false;  }   private async void StopServerButtonClicked(object sender, RoutedEventArgs e)  {  // Update the UI  ServiceStartButton.IsEnabled = false;  ServiceStopButton.IsEnabled = false;  LocalServerStartButton.IsEnabled = true;  LocalServerStopButton.IsEnabled = false;   try  {  // Stop the server.  await LocalServer.Instance.StopAsync();  }  catch (Exception ex)  {  MessageBox.Show(ex.Message, "Failed to stop server");  }   // Clear references to the services  _localFeatureService = null;  _localMapService = null;  _localGeoprocessingService = null;  }   private void NavigateButtonClicked(object sender, RoutedEventArgs e)  {  // Return if selection is empty  if (ServicesListbox.SelectedItems.Count < 1) { return; }   try  {  // Get the full text in the selection  string strFullName = ServicesListbox.SelectedItems[0].ToString();   // Create array of characters to split text by; ':' separates the service name and the URI  char[] splitChars = { ':' };   // Extract the service URL  string serviceUri = strFullName.Split(splitChars, 2)[1].Trim();   // Navigate to the service  Process.Start(new ProcessStartInfo(serviceUri) { UseShellExecute = true });  }  catch (Exception ex)  {  MessageBox.Show(ex.Message, "Couldn't navigate to service");  }  }  } }

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.