Link to home
Start Free TrialLog in
Avatar of zip001
zip001

asked on

Problem with Shell32.dll in thread: BadImageFormatException - Invalid access to memory location

Hi,

What have I done:
I've adapted and tested the code from http://www.vbforums.com/archive/index.php/t-422460.html and it works fine in the sub main of a console application.

Then I wrapped the code up in a class and it throws an error whenever I run the subroutine from another thread or from timer_elasped.

What the code does:
The subroutine goes into control panel --> Network Connections --> Local Area Connection (or any other connection), iterate through the verbs to disable, then enable that connection

What went wrong:
The following exception has been thrown when it tried to get the verbs from Shell32.FolderItem
{System.BadImageFormatException}
    System.BadImageFormatException: {"Invalid access to memory location. (Exception from HRESULT: 0x800703E6)"}
    Data: {System.Collections.ListDictionaryInternal}
    HelpLink: Nothing
    InnerException: Nothing
    Message: "Invalid access to memory location. (Exception from HRESULT: 0x800703E6)"
    Source: "Interop.Shell32"
    StackTrace: "   at Shell32.FolderItem.Verbs()
   at (my app)..ctor(String ConnectionName) in (my file path):line 83"
    TargetSite: {System.Reflection.RuntimeMethodInfo}

I've attached my adapted version of the source code, which is largely the same as the one in the URL, except I've removed some "console.writeline" and hard-wired the connection name.

The attached code works in "sub main" and I've referenced the relevant dll etc. So why doesn't it work on a separate thread or in a timer_elasped sub?
If Not My.Computer.Network.IsAvailable Then
 
            ' Control Panel Identifier 
            Const ssfCONTROLS = 3
 
            ' Generate Shell item 
            Dim ShellApp As New Shell32.Shell()
            ' Obtain the Control Panel 
            Dim ControlPanel As Shell32.Folder = ShellApp.NameSpace(ssfCONTROLS)
 
 
            Dim NetworkFolder As Shell32.Folder
            Dim LANConnection As Shell32.FolderItem
 
            ' Loop through the items in the control panel and obtain the Network Connections folder 
            For Each FolderItem As Shell32.FolderItem In ControlPanel.Items()
                If FolderItem.Name = "Network Connections" Then
                    ' When found - exit the loop 
                    NetworkFolder = FolderItem.GetFolder
                    Exit For
                End If
            Next
 
            ' Debug check 
            If IsNothing(NetworkFolder) Then
                Console.WriteLine("Error - No network folder found")
                Exit Sub
            End If
 
            ' Obtain the appropriate connection record 
            For Each FolderItem As Shell32.FolderItem In NetworkFolder.Items()
                If FolderItem.Name = _ConnectionName Then
                    ' When found - exit the loop 
                    LANConnection = FolderItem
                    Exit For
                End If
            Next
 
            ' Debug check 
            If LANConnection Is Nothing Then
                Console.WriteLine("Error - No LAN entry was not found")
 
 
 
            End If
 
 
 
            Const EnableVerb As String = "En&able"
            Const DisableVerb As String = "Disa&ble"
 
            ' Run through all available options and obtain the appropriate action 
' ***** error here ***
            For Each Verb As Shell32.FolderItemVerb In LANConnection.Verbs
                If Verb.Name = DisableVerb Then
 
                    Console.Write("Current Status: Enabled --> Trying to disable")
                    Verb.DoIt()
                    Exit For
                End If
            Next
            ' wait for 5 seconds before enabling again
            Threading.Thread.Sleep(5000)
 
            ' Enable it...
            For Each Verb As Shell32.FolderItemVerb In LANConnection.Verbs
                If Verb.Name = EnableVerb Then
                    Console.Write("Current Status: Disabled --> Trying to enable")
                    Verb.DoIt()
                    Exit For
                End If
            Next
 
        End If

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of AkisC
AkisC
Flag of Greece image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of zip001
zip001

ASKER

I see...

The problem is this is code for a windows service, so there is no UI.

The windows service is quite big, so I put the initialization code in a background process, i.e. a different thread, I guess I can work around that pretty easily.

However, the code is also accessed through a timer, which creates another thread. I tried inheriting the service class so it can be the schronizing object of the timer, but it still creates another thread.

My current solution is to put that code into another app, and start it using the process class. It's silly, but it works
As I wrote in the past...Limited memberships. The asker gets the guidelines and then he/she has no points to award and the result is this.
I'd suggest close the question with no points refunded.

Out of curiosity
zip001, did my answer assist you at all?
Avatar of zip001

ASKER

AkisC,

Yes and No.

From your answer I realised that everything has to be on the same thread. As mentioned in my last post, I couldn't do it with a Windows service.

I tried to close the question a few times, each time it says it will post a comment here and if no one objects it will close the question in 4 days. It just didn't happen that way.