Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

Async Delegates and Security with PInvoke (Access Denied Errors)


:P
On this page:

Here’s an interesting one I ran into today with Asynchronous Delegates and PInvoke calls:

 

In West Wind Web Monitor I have a splash screen that pops up when the app starts. It runs on a separate thread so that it can pop immediately before the main form of the application loads. The form also contains a button that uses the Win32 ShellExecute API to load a URL for registration. It all worked well until yesterday.

 

Btw, the code to make the ShellExecute call looks like this:

 

[DllImport("Shell32.dll")]

private static extern int ShellExecute(int hwnd, string lpOperation,

      string lpFile, string lpParameters,

      string lpDirectory, int nShowCmd);

 

public static int GoUrl(string Url)

{

      string TPath = Path.GetTempPath();

      int Result = ShellExecute(0,"OPEN",Url, "",TPath,1);

      return Result;

}

 

Anyway, a while back I decided instead of creating a brand new thread to just use an Async Delegate and use BeginInvoke to call the splash routine from it thinking that it would be more efficient (probably not since the Delegate probably has to fire a new thread too). Today getting ready for deployment and shipping out of the app I casually noticed that the button code that goes to the URL was not working. Turns out that the ShellExecute API call ends up failing with a value of 5 – Access Denied.

 

After some back and forth I realized that the same code was working fine in the main part of the application – the Splash screen also doubles as the About form. When I brought up the form from the Help menu it all worked fine and dandy.

 

So. it turns out that using the Delegate causes this problem to occur. If I start up my own thread the code runs just fine. Async Delegates use the .Net Thread pool and apparently these threads don’t have the same rights as the mainline application. Just to be sure I checked the current user credentials and it looks like my credentials. So the permissions issue here is not user level but .Net permissions level.

 

///*** This causes ShellExecute to fail with error 5

MethodInvoker delSplash = new MethodInvoker(Startup.RunSplash);

delSplash.BeginInvoke(null,null);                 

 

///*** This doesn’t

ThreadStart delSplash = new ThreadStart(Startup.RunSplash);

Thread NewThread = new Thread(delSplash);
NewThread.ApartmentState = ApartmentState.STA;

NewThread.Name = "Splash";

NewThread.Start();

 

Where the RunSplash method does nothing more than load up the Splash form. Note that the ApartmentState seems to be significant - without STA mode I still got flakey behavior, but it worked most of the time.

 

Now I’m wondering exactly what the permission level of the Delegate threads in the Thread Pool are and what else might not work. Up until this point I’ve been rather indiscriminate about the use of threads or delegates, but this may be one more reason to use new Threads instead of delegates.

 

If somebody has run across info about this let me know…

?>


The Voices of Reason


 

Calum
April 28, 2005

# re: Async Delegates and Security with PInvoke (Access Denied Errors)

And one and a half years later, you've solved all my problems...

Thanks!

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2025