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.BadImageFormatExce ption}
System.BadImageFormatExcep tion: {"Invalid access to memory location. (Exception from HRESULT: 0x800703E6)"}
Data: {System.Collections.ListDi ctionaryIn ternal}
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.Runtime MethodInfo }
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?
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.BadImageFormatExce
System.BadImageFormatExcep
Data: {System.Collections.ListDi
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.Runtime
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
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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?
I'd suggest close the question with no points refunded.
Out of curiosity
zip001, did my answer assist you at all?
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.
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.
ASKER
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