• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 7293
  • Last Modified:

COMException when binding a new System.DirectoryServices.DirectoryEntry object to IIS

I'm experiencing a rather interesting problem using the DirectoryEntry object.  Here is the code in question:

try
{
      System.DirectoryServices.DirectoryEntry iisRoot = new System.DirectoryServices.DirectoryEntry("IIS://" + serverAddress + "/W3SVC/1/Root");
}
catch(Exception ex)
{
      Console.WriteLine(ex.Message);
}

Although I haven't included the rest of the method's code, it should suffice to say I'm just using this DirectoryEntry object to create a new virtual directory.  The code seems simple enough, and works perfectly fine when the "serverAddress" parameter is "127.0.0.1" or "localhost" or "192.168.1.100" (my network IP address).  However, as soon as I put in "192.168.1.101" (or the address of any other computer, for that matter) the application throws this:

An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in system.directoryservices.dll
Additional information: The RPC server is unavailable

The odd thing is that the catch block doesn't catch the exception.  VS.NET (in debug mode) just throws me that error and breaks the debug run and won't show me any exception related information (InnerException, StackTrace, etc.).  So, because of that, I can't drill down at all to see what might be causing the problem at a deeper level.

My dev machine is running: Windows XP Professional (with Service Pack 2), IIS 5, Visual Studio .NET 2003.  I'm wondering if it may be an issue with Service Pack 2, but I'm not sure.

Ideas?  Solutions?

Thanks.
0
BurntSky
Asked:
BurntSky
1 Solution
 
dunglaCommented:
When you input IP address of another computer, your code will make a RPC call to remote machine (specified by IP, computer name). At remote machine, when your code prepare to executed, that machine will check for authorization of user who execute the code (mean your account in your local machine). If not authorized then the code will thru exeception.

You can try...catch (COMException ex) for more detail. When you create new instance of DirectoryEntry, remember to parse username and password as well

   System.DirectoryServices.DirectoryEntry iisRoot = new System.DirectoryServices.DirectoryEntry("IIS://" + serverAddress + "/W3SVC/1/Root", "username", "password");
0
 
BurntSkyAuthor Commented:
I've tried passing the appropriate username and password when creating the DirectoryEntry instance, however, it acts the exact same way as without it; when executed against my local machine it works fine, against a remote machine, it doesn't work.  Even if I enable DMZ on my router and forward all calls to my machine and then execute the code against my external IP it throws the same error.  Also, I would think that if the problem was invalid user credentials it would throw a different error (something relating to incorrect permissions).

Concerning the try...catch block: it doesn't work.  I've tried numerous ways around it and it's a very, very odd thing.  If I replace my catch block with:

catch(COMException ex) { ... }
or even:
catch { ... }

it skips right over it and throws the error (instead of executing the code in catch block).  I'm guessing it might be a bug related to poor exception handling for unmanaged code.
0
 
UritsukidojiCommented:
Could the exception be thrown asynchronously (i.o.w. the excpetion isn't directly thrown when the

new System.DirectoryServices.DirectoryEntry("IIS://" + serverAddress + "/W3SVC/1/Root", "username", "password");

is executed?

If you're using a web application, try if you can catch the exception at global scope in global.asax.cs:

protected void Application_Error(Object sender, EventArgs e)
{
  Exception e = Server.GetLastError();
  if (e is COMException){
   ...
  }
}

If it's a Windows.Forms application, see if one ofthese articles can help you:

User Friendly Exception Handling
http://www.codeproject.com/dotnet/ExceptionHandling.asp

Unhandled exception handling:
http://www.codeproject.com/dotnet/unhandledexceptions.asp

.NET Thread & application level exception handling
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/exceptdotnet.asp

Good luck, Wiebe
http://www.netindustry.nl/blog
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
dunglaCommented:
Check for your RPC services is running and RPC service in remote machien is running?
0
 
testnCommented:
make sure that
1. firewall is off (to allow RPC)
2. two servers are in the same domain
3. account that use to run that code must be able to authenticate on the other server
4. and have permission enough to get that data

very likely that it has something to do with sp 2 since it turns firewall on by default
you may follow this instruction to carefully enable RPC port for local subnet
http://www.microforge.net/kb/39
0
 
BurntSkyAuthor Commented:
@ Uritsukidoji:

I hadn't thought about the possibility of it being run asynchronously.  Although, what good would that do?  The application can't move forward until the code executes and instantiates the DirectoryEntry object anyway, so why run it on a different thread?  I guess the CLR might create new threads for executing native/unmanaged code and pausing the existing thread until the new one completes...

Regardless, I'm still not able to trap the error.  I'm working with a WinForms application so I've tried attaching event handlers to the Application.ThreadException event and this is the most I can get out of it:

Exception Type:  System.Runtime.InteropServices.COMException
COMException Error code:  -2147023174
Stack Trace:
   System.Runtime.InteropServices.COMException (0x800706BA): The RPC server is unavailable
   at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
   at System.DirectoryServices.DirectoryEntry.Bind()
   at System.DirectoryServices.DirectoryEntry.get_IsContainer()
   at System.DirectoryServices.ChildEnumerator..ctor(DirectoryEntry container)
   at System.DirectoryServices.DirectoryEntries.GetEnumerator()
   at xxx.xxx.xxx.CreateVirtualDirectory(String serverAddress, String virDirName, String path) <--- the method containing the code in my original post.

I just wish the message was a little more detailed.


@ dungla:

Yes, the RPC service is running (however, I'm not sure if theres a configuration issue).  Like I said before, when I execute it locally against my machine (intranet), it works fine, however, if I execute it against my external (internet) ip address it throws the aforementioned exception.


@ testn:

1. firewall is off.
2. i would assume my machine wether externally or internally would be on the same domain (i'm not really a network specialist though.  nor an active directory specialist for that matter)
3. the account should be able to authenticate... as i said above, i'm no network specialist, so i'm not sure what the exact requirements are.
4. account should have access (however, if it didn't i wouldnt expect to get the "RPC server is unavailable" message.  i would expect a permission/credentials related message).


After playing around with it some more, I'm guessing the issue isn't necessarily the code.  It might be the way my network is set up.  I'm not really sure what requirements there are for active directory.  I really just wish the exception was more detailed so i could pinpoint the issue easier.

Any more suggestions would be much appreciated.  Thanks
0
 
dunglaCommented:
BurntSky,

Sure, when you run the code in local machine that mean you was authorized to do that. When you run the code to create CreateVirtualDirectory at remote machine, you need to make sure that.

I already have a question about connect to remote machine in network, you can refer to it for more information

http://www.experts-exchange.com/Programming/Programming_Languages/Visual_Basic/Q_21234441.html

You can try to connect to remote machine by call "net use \\computername" to make sure you have permission to do that. If it succeed, then you can run your code without worry anything
0
 
BurntSkyAuthor Commented:
Well, I guess the question is a little too complex to get a straight forward solution.  You're probably right about it being an authorization issue though.  I tried NET USE and NET VIEW, both of which work fine against my local machine, but against a remote machine I'm getting an "Access Denied" message with no prompt for a username/password.  I'm assuming this is a result of how my network and/or workstations are set up.  Maybe I'll just go pick up a book on the subject or something instead.

Thanks for the help.
0
 
dunglaCommented:
I think it just because your network. Maybe two computers not in the same domain (if domain controller), or both are WinXP SP2
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now