List of ArcObjects posts:
- Introduction
- Getting Started
- Extending the Framework
- Workspace
- Workspace Provider
- Workspace is Down
- Licensing
- Com Releaser
- Cursors and IsRecycling
- WorkspaceUtils
- Multithreading
- Mocking
List of ArcObjects posts:
This post is the sixth post in my ArcObjects series.
This is a direct continuation from my post ArcObjects: Workspace Provider.
Back in March our DB was down over the night and unlike all the other systems ours didn't just resume work after the DB was brought up, it needed the team’s involvement.
The Exception we got was:
System.Runtime.InteropServices.COMException was unhandled
HelpLink=esri_csGeoDatabase.hlp
Message=Failure to access the DBMS server [Microsoft SQL Server Native Client 10.0: Communication link failure] [SERVER.SCHEMA.LAYER_NAME]
Source=esriDataSourcesGDB.SdeWorkspace.1
ErrorCode=-2147155559
StackTrace:
at ESRI.ArcGIS.Geodatabase.IFeatureClass.Search(IQueryFilter filter, Boolean Recycling)
InnerException:
So I recreated the error by restarting the "SQL Server (MSSQLSERVER)" service in our DB with some special code.
Symptoms:
1. The IWorkspace status:
((IWorkspace) _workspace).Exists();
Returns true
2. Then I started looking at other places like ESRI’s diagrams. One of the diagrams:
(Not mine EDN's)
IWorkspaceStatus sounded a bit off to me that it is under WorkspaceFactory and not under Workspace but the real problem was what was written in the documentation. There are no implementations of this according to EDN…
But I found another interface IWorkspaceFactoryStatus, managed to point it to my workspace and got back:
((ESRI.ArcGIS.Geodatabase.IWorkspaceFactoryStatus )workspaceFactoryTemp).PingWorkspaceStatus((ESRI.ArcGIS.Geodatabase.IWorkspace)_workspace)
{System.__ComObject}
[System.__ComObject]: {System.__ComObject}
ConnectionStatus: esriWCSAvailable
Workspace: {System.__ComObject}
I just thought to myself how can it possibly be Available, until I look at the documentation at esriWorkspaceConnectionStatus:
Available doesn't mean it's up - just that it was lost and now is available. And I was sure it meant something else… (Couldn’t they name it something like LostAndNowAvailable or AvailableToReconnect? – Available just does not cut it!!!).
The end result looks like this:
Checking if the workspace is running:
If it’s down recreate it (and if it can’t be recreated throw an exception):
You can also look at the full code here.
Hopefully next time the DB is down it will just recreate IWorksapce…
Resources:
This post is the fifth post in my ArcObjects series.
As I mentioned in my previous post you cannot create a workspace you have to receive it from some place. That place is called the WorkspaceFactory (or as usual IWorkspaceFactory). Now since getting the workspace is useful and usually only done once we put it in a singleton class named WorkspaceProvider.
As can be seen in the IWorkspaceFactory documentation there are many implementation of this interface. The implementation differ in the Space where the workspace is doing it’s work:
These classes provide the interface to connect to the Space the same way ArcDesktop tools do so by the Open method. You can either use a file containing the connection (created in ArcCatalog), use IPropertySet a list containing the connection information (see here for details) or by using connection string (the other options just use this option behind the scene).
Sde connection string are separated to two categories (more details in one of my previous posts: ArcSDE: Connection to the Geodatabase):
Where:
As you can see direct connection doesn’t use the Sde service number, that is because it doesn’t use the Sde service (it does all the work at the client). Most times you won’t need to change the Server type so that’s out as well. My code only uses Direct Connection string (since ESRI recommends using it).
In my experience most applications will use only one IWorkspace – the one connecting them to the application Sde. For that reason WorkspaceProvider uses DefaultDbConfigSection which is both a Configuration Section and a Connection String builder (I use it for both the Sde and regular DB Connection string). To prevent unnecessary creation of IWorkspace objects WorkspaceProvider will also store the last IWorkspace created and the connection string used to create it.
As it is the only public methods needed for this class are:
1. Using Sde Connection String from web/app.config file:
2. Using Sde Connection String provided:
3. Using a Cad file:
4. Using either GDB or MDB file paths:
The full code can be found here.
Most of the code is self-explanatory except one part – getting a cached Workspace. Now you might think this is the most simple part but when taking into account that sometimes connections fail, servers are down and Murphy is constantly prowling than you must be ready for that “What If…”. I will write more on this in one of the next posts.
The rest of the code is pretty much self-explanatory and can be found in my CodePlex Project, or directly here.
Resources:
MSDN: How to: Create Custom Configuration Sections Using ConfigurationSection
When connection to a database SDE there are two ways to achieve that:
(From ESRI site the ArcCatalog connection screen)
1. Regular connection using Server, Service (enter the SDE service number), database, user(optional), password(optional)
The regular way uses a service on the database machine which must be running. The service can be found in:
Right click on My Computer –> Manage:
Computer Management –> Services And Applications –> Service:
By Default the service will be called “ArcSde Service(esri_sde)”:
As you can see I am not using the regular way (the service is not marked as started). For both 10 and 9.3.1 ESRI advices not to use it this way since it does all it’s work on the DB machine.
Note: if you are using several sde services than the Service port will differ than the default of 5151. If you are unsure about the number than look in the DB server at services file (located at: c:\Windows\System32\drivers\etc and has no extension). The file contains lines for services, their port and connection protocol:
esri_sde 5151/tcp #ArcSDE for SqlServer
2. Direct Connection using Server, Service, database, user(optional), password(optional)
The difference in the connection is only in Service, for example in SQL Server: “sde:sqlserver:<sql_server_instance>” (for any other server use this ESRI reference the forth step).
This connection doesn’t use the SDE service. It connects directly to the DB and does all it’s work on the client. If you are using only this connection type then I advise you to change the “ArcSde Service(esri_sde)” to run Manually instead of Automatic – it just means that at startup the service won’t be turned on.
I have created all my SDE connection but now my team mate Bob needs a connection, What do I do?
Well I usually save the connections in one of the team’s network folders with a bat file called install connections. Here is how I do that:
xCopy *.sde %APPDATA%\ESRI\Desktop10.0\ArcCatalog /I
(The /I is for creating the sub folder when they don’t exist (like when you never opened ArcCatalog…))
Resources:
ESRI: Geodatabase connections in ArcGIS Desktop
ESRI: Preparing database connection files
Last month I got a new assignment to develop a tool that changes the layers’ connection in a MXD file and publish it in ArcGis Server. It is fairly easy to do it using ArcMap but we have too many environments/servers and whatever we can automate should be automated.
Since then the team went to a Systematics Event (ESRI local provider) where they talked about the new stuff in version 10.1, namely that publishing will only support MSD files (not MXD files) – so the task got changed a bit. For more information on MSD functionality and Performance considerations.
Finding how to change the connection of the layers was easy enough with the IMSDHelper interface:
We simply iterate through all the maps and all the inner layers and change the connection to the given one.
But what about Publishing the MSD automatically? This proved to be a bit more problematic. It was fairly easy to find a Python script using arcPy that publishes MSD files. But less so on ArcObjects code, in the end I found this forum post which led me to this code (just run it through Google Translate since it’s in Chinese). The code looks like this:
This is to set the default values of my organization:
(there are more settings that can be found here)
I found that it is best to look at existing services, for that I added the capability of getting your service settings in XML format:
The output of this method looks like this:
As you can see the properties in the XML correspond perfectly with the properties settings.
To test the creation of the service you can look at ArcGis Server Manager:
http://ServerName/ArcGIS/manager/default.aspx
Where you can tweak the settings (as you can see I had 5 tries till I got it right…).
Also you can test the service using the REST API :
http://ServerName/ArcGIS/rest/services
Looking into the FeatureServer link you will find in the bottom “Supported Operations: Query” where you can test the Feature service queries:
Some points:
I have posted the complete tool in my Codeplex project: ArcGisServerTools, MsdUtils, ArcGisServerUtils.
Resources:
ArcGis Server Forum: Promote map service from one server stage to another in automated fashion?
ArcObjects Forum: Publish MXD to server in ArcObjects C#
Keywords: MSD, ArcObjects, ArcGis Server, ESRI
For the past several years I have been having a problem with my home computer (Windows XP), the problem is not so severe just annoying (though I guess for some people it will be much more severe). My problem? from time to time the application I work on losses it’s focus for a second and then either:
a. gets it back (when it’s in windowed state)
b. another application gets the focus (when it’s full screen applications).
My solution to the problem was using only windowed applications but it is too annoying when watching movies or sometimes impossible when playing games.
From time to time I would search the web for solutions and find forums that advise people to open Task Manager (or other similar applications) and just see what application is stealing the focus – the problem is you need to be fairly fast to catch the bugger (especially when games and movies demand your full attention). Other solutions were with specific applications that caused the problem like AVG anti virus (in one of its old versions). I have tried formatting the computer but the problem returned (meaning it must be some application I always use).
So I have decided to fix (or at least find the problematic application) myself. I first found a windows function that partially does what I wanted – GetForegroundWindow, then searching for it with C# I found a solution at StackOverflow site a bunch of invoke methods that return the current focused window information, all that was left was wrapping it in a console application and using it.
In the end running the little app at home found the problem:
27/11/2011 20:22:10:C:\WINDOWS\System32\rasautou.exe -> Connecting Cables012...
For the past several years my computer has been the dial up computer for the internet. Cables012 is that connection. Thinking to solve connection problems I enabled “Establish a dial-up connection whenever a computer on my network attempts to access the Internet”:
I thought to myself that this option will just reconnect to the internet when the connection is down, well it does that and also steals the windows focus whenever it feels like and at exactly midnight it also activate what I like to call “Blinking Window Mode” when at least one window will appear in the general top left area of the screen and disappear before you can read what it says…
Well the fix was easy enough just uncheck this option and restart the connection. This whole thing was a surprise since I was sure I had some kind of funky spyware app installed which caused all of this…
I have added the source code for this little app to my Codeplex project, and also a release exec (for the non programmers who reach this site).
Keywords: Windows, Full Screen, Focus