VB6: Automation error The remote procedure call failed - vb6

In my VB6 application sometimes in some customer PC we get error like
Automation error
The remote procedure call failed.
The error comes for the code shown below
Dim WithEvents Web_popup As SHDocVw.InternetExplorer
Set Web_popup = Nothing
Set Web_popup = New SHDocVw.InternetExplorer
Set ppDisp = Web_popup.Application
Also for the below code
Dim iE As New SHDocVw.InternetExplorer iE.Navigate "www.example.com", 4 + 8
iE.Visible = True
What may be the reason for these errors? How to solve it?

You should include more information when asking for help. More importantly, you should point exactly which lines are causing the error. That being said, it sounds to me that you are not checking the ready state of the download of html to Explorer. Interacting with a web page before the web page has been completely download will cause this symptom.
If you are checking the ready state, the only other way I was able to produce the error was turning on protected mode in Internet Explorer. Some websites cause the error when Protected mode is on.

Related

Send ENTER key to console in form application in VB.NET

edit: My issue was never quite resolved, but the answer below provided an interesting result.
The app will eventually be called by a powershell script and in this situation, I don't have the issue explained below. No additional {ENTER} is required in the PS console, so no more issue! I couldn't care less if an extra ENTER is required when my app is launched manually via cmd.exe
Problem: In a VB.NET
form app, I'm unable to get the console back to it's "default" state after the code is finished running. I need to press enter manually.
My app can also be executed from command line (in this case, no form is opened. Code is being executed automatically and output sent to console for user to see what happens)
I call AttachConsole(-1), run some code, and when everything's finished I see my latest message in console, but it's as if the process wasn't quite finished.
I have tried SendKeys.SendWait("{ENTER}"). It works well, but only when the console is the current focus. If I click outside the console while the code is running, the ENTER key is sent to whichever window I made active.
So I tried to make the console the current window:
Dim bProcess As Process = Process.GetProcessesByName("cmd").FirstOrDefault()
SetForegroundWindow(bProcess.MainWindowHandle)
// I also tried AppActivate(bProcess.Id)
SendKeys.SendWait("{ENTER}")
FreeConsole()
Nope, the ENTER key will still be sent somewhere else and not to the console. But it does make the console blink orange, so SetForegroundWindow seems to do something...
Any help will be greatly appreciated :)
EDIT
In response to #TnTinMn's answer:
FreeConsole()
// SendKeys.SendWait("test")
PieceOfCodeFromTnTinMn()
Same behavior as I've had so far: This will send the SendKeys.SendWait("~")command "outside" the console if it loses focus while the code is running.
BUT with the 2nd line above un-commented, "test" is sent outside the console and SendKeys.SendWait("~") is sent to the console, as expected.
I'm still trying to figure out what is happening here...
You can use the VB Interaction.AppActivate Method to activate the parent console prior to calling SendKeys.SendWait. This requires that you obtain the ProcessID of the console window that is the parent process of your application.
One way to do this is using Windows Management Instrumentation (WMI). The following is not pretty, but it appears to work. You would execute this after calling FreeConsole
Using currentProcess As Process = Process.GetCurrentProcess
Dim query As New SelectQuery()
Dim props As New StringCollection
props.Add("ProcessId")
props.Add("ParentProcessId")
With query
.ClassName = "Win32_Process"
.Condition = $"ProcessId={currentProcess.Id}"
.SelectedProperties = props
End With
Dim parentProcessId As Int32
Using searcher As New ManagementObjectSearcher(query)
Using mos As ManagementObjectCollection = searcher.Get
Using en As ManagementObjectCollection.ManagementObjectEnumerator = mos.GetEnumerator
If en.MoveNext() Then
parentProcessId = CInt(en.Current.Item("ParentProcessId"))
End If
End Using 'en
End Using ' mos
End Using 'searcher
If parentProcessId <> 0 Then
AppActivate(parentProcessId)
SendKeys.SendWait("~")
End If
End Using 'currentProcess

MSXML2.XMLHTTP , Method 'open' of object 'IServerXMLHTTPRequest2' failed

Dim objHTTPRequest As MSXML2.XMLHTTP
Set objHTTPRequest = New MSXML2.XMLHTTP
With objHTTPRequest
.Open MethodName, strRequest, Asynchronous, strUserName, mstrPassword
'___________more code here___________
End with
I am trying to create a serverConnection object by getting the input parameters from the user using a visual basic form. When run the code, I am getting the following error when executing the above code part. I am working on a word add-in and this error is only occurring when I run the code through vb and the created .dll for the product is working properly with Word.
The following error occurred while submitting this request to a server: Method 'open' of object 'IServerXMLHTTPRequest2' failed
The server address() may be incorrect
in here,
strRequest= "/api/a1/Properties"
If anybody could, Please tell me why is this happening. Because of that error, I am unable to debug the code for further modifications.

VB6 program fails opening Excel 2007 with Automation Error Library not registered

I created this VB6 program on my Windows 7 32bit machine with Office 2010 32bit, which runs fine. Tested it on a Windows 8 64 bit machine with Office 2013 32bit, it works. On one machine with, Windows 7 64 bit and Office 2007(32 bit only) it throws an error during the following piece of code.
The actual error message:
Run-time Error –2147319779 (8002801d) Automation error, Library not
registered
VB6 Code:
If (excel_app Is Nothing) Then
Set excel_app = CreateObject("Excel.Application")
Else
Set excel_app = GetObject(, "Excel.Application")
End If
excel_app.Visible = True
excel_version = excel_app.Application.Version
Set wBook = excel_app.Workbooks.Open(directory_path & "\templates\book1.xlsm")
So it is throwing the error when I open book1. It actual does open it and it has a macro run on Workbook_Open(), this runs right through seemly fine. After it finishes and processing of the program returns to the VB6 program it throws the error.
Here are the project references:
Has anyone come across this and what would be the fix?
[EDIT]
I am obviously doing something wrong here my error handler is throwing an error.
I did try one other thing and that was removed "Set wBook = " and it didn't throw an error. I have placed "Set wBook = " back since then, as I do need it further on in my code.
Dim wBook As Workbook
Dim excel_app As Object
On Error GoTo trialhandler
If (excel_app Is Nothing) Then
Set excel_app = CreateObject("Excel.Application")
Else
Set excel_app = GetObject(, "Excel.Application")
End If
excel_app.Visible = True
excel_version = excel_app.Application.Version
Set wBook = excel_app.Workbooks.Open(directory_path & "\templates\book1.xlsm")
MsgBox ("Exiting")
Exit Sub
trialhandler:
Dim source_string As String
source_string = excel_app.Source 'Error here
MsgBox ("My Error 1:" & source_string)
excel_app.Err
MsgBox ("My Error 2:" & excel_app.Err.Number & " " & excel_app.Err.Description)
Exit Sub
I had Office 2013 installed on this previously, then uninstalled it and placed 2007 on it, could this have any impact? Or the fact that I have created this program with reference to Excel 2010 and now I'm trying to run it against Office 2007? Though it works on the other machine with 2013. Grasping at straws here.
[EDIT 2]
It has passed the initial error to throw exactly the same error later on. This piece imports an mdb table. There must be some early binding left over
With wBook.Worksheets("Seal Register").ListObjects.Add(SourceType:=0, Source:=Array( _
"OLEDB;Provider=Microsoft.ACE.OLEDB.12.0;Password="""";User ID=Admin;Data Source=" & db_full_path & ";" _
, _
"Mode=ReadWrite;Extended Properties="""";Jet OLEDB:System database="""";Jet OLEDB:Registry Path="""";" _
, _
"Jet OLEDB:Database Password="""";Jet OLEDB:Engine Type=5;Jet OLEDB:Database Locking Mode=0;Jet OLEDB:Global Partial Bulk Ops=2;" _
, _
"Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="""";Jet OLEDB:Create System Database=False;" _
, _
"Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;" _
, _
"Jet OLEDB:SFP=False;Jet OLEDB:Support Complex Data=False"), _
Destination:=Range("A" & row_number)).QueryTable
.MaintainConnection = False
.CommandType = xlCmdTable
.CommandText = Array(db_table_name)
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = 1
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = True
.SourceDataFile = db_full_path
.ListObject.DisplayName = "Table_" & db_table_name
.Refresh BackgroundQuery:=False
End With
There no reason to think this is a vb error.
Returns or sets the name of the object or application that originally generated the error.
object.Source [= stringexpression]
Arguments
object
Always the Err object.
stringexpression
A string expression representing the application that generated the error.
Remarks
The Source property specifies a string expression that is usually the class name or programmatic ID of the object that caused the error. Use Source to provide your users with information when your code is unable to handle an error generated in an accessed object. For example, if you access Microsoft Excel and it generates a Division by zero error, Microsoft Excel sets Err.Number to its error code for that error and sets Source to Excel.Application. Note that if the error is generated in another object called by Microsoft Excel, Excel intercepts the error and sets Err.Number to its own code for Division by zero. However, it leaves the other Err object (including Source) as set by the object that generated the error.
Source always contains the name of the object that originally generated the error — your code can try to handle the error according to the error documentation of the object you accessed. If your error handler fails, you can use the Err object information to describe the error to your user, using Source and the other Err to inform the user which object originally caused the error, its description of the error, and so forth.
From Automating Microsoft Office 97 and Microsoft Office 2000
Lori Turner
Microsoft Corporation
March 2000
PROBLEM:
My Automation client worked fine with the Office 97 version of my application. However, I rebuilt my project and it works fine with Office 2000 but now fails with Office 97. What could be wrong?
New versions of Office include new features and enhance some of the existing ones. To provide clients with programmatic access to these new and enhanced features, the object models must be updated. Because of this update, a method may have more arguments for Office 2000 than it did with Office 97.
The new arguments to existing methods are usually optional. If you use late binding to the Office Automation server, your code should work successfully with either Office 97 or Office 2000. However, if you use early binding, the differences between the 97 and 2000 type libraries could cause you problems in the following situations:
If you create an Automation client in Visual Basic and reference the Office 2000 type library, your code might fail when using an Office 97 server if you call a method or property that has changed.
If you create an MFC Automation client and use the ClassWizard to wrap classes from the Office 2000 type library, your code might fail when using an Office 97 server if you call a method or property that has changed.
To avoid this problem, you should develop your Automation client against the lowest version of the Office server you intend to support. For the best results in maintaining compatibility with multiple versions of Office, you should use late binding. However, if you choose to use early binding, bind to the type library for the earliest version of the Office server you want to support. To illustrate, if you are writing an Automation client with Visual Basic and want that client to work with Excel 97 and Excel 2000, you should reference the Excel 97 type library in your Visual Basic project. Likewise, if you are writing an Automation client using MFC, you should use the ClassWizard to wrap the Excel 97 type library.
For more information, please see the following article in the Microsoft Knowledge Base:
Q224925 INFO: Type Libraries for Office 2000 Have Changed

Watin accessing localhost

When executing the c# code in MSTest involving WatiN
var browser = new IE("http://localhost:56034/");
The web page is displayed in IE but after about a minute, I receive the error
Timeout while waiting for main document becoming available with the error message
Timeout while waiting for main document becoming available
The code
var browser = new IE("http://www.bing.com/");
works fine.
I am running IIS Express 7.5. Since I am new to the WatiN I am hoping that I am missing something simple.
Following the advice in http://spin.atomicobject.com/2010/12/15/watin-and-com-errors-enable-ie-protected-mode-for-local-intranet-zone, turning ON protected mode for the intranet zone in IE 8 solved the problem.

WebBrowser control, isolation and IE8 InPrivate mode

I have a need to run some automation tasks in a web browser control but I seem to be facing a few limitations/unknowns that I'm not 100% sure how to resolve. The application I'm running is not for public release, so I can enforce a prerequisite that IE8 is installed.
GeckoFX (http://geckofx.org) would be great except it does not offer me an acceptable way to manipulate the DOM as I would using the WebBrowser's InvokeMember method on HtmlElement objects.
WebKit.net would be even better but it's too early in its development to offer the functionality I need to do this either.
This leaves me with the WebBrowser control. The problem with WebBrowser though is that it just runs IE, which is a big fat shared environment with all processes. In other words, all instances share cookies, sessions, proxy settings, etc.
Here's what I want:
At the end of an automation session, cookies/sessions/cache objects are not retained. Rather than clearing the global Temporary Internet Files folder, is there a way for me to access the InPrivate mode exposed by IE8?
If there is a way to access InPrivate browsing, is it possible for me to run two InPrivate-mode sessions side-by-side isolated from each other?
Ideally I'd like to be able to run multiple isolated automation tasks in separate threads, each with its own private browser control, each with its own isolated session/environment that is not retained when the task completes.
Any help or input into this would be appreciated!
No, you cannot run the WebBrowser control in InPrivate mode; it's simply not a supported scenario.
Yes, you can run two instances of IE in InPrivate mode and isolate them from each other.
Use the command line: iexplore.exe -private -nomerge
Here's some code that will give you access to an InPrivate IE
Friend Function Open(Optional ByVal Url As String = "about:blank", Optional ByVal WindowState As ProcessWindowStyle = ProcessWindowStyle.Hidden) As WebBrowser
On Error Resume Next
Dim Start As New ProcessStartInfo
Dim Windows = New ShellWindowsClass
Dim Count = Windows.Count
Start.FileName = "iexplore.exe"
Start.Arguments = "-private -nomerge " & Url
If WindowState = ProcessWindowStyle.Hidden Then
Start.WindowStyle = ProcessWindowStyle.Minimized
Else
Start.WindowStyle = WindowState
End If
Process.Start(Start)
Wait.Reset()
Do
If Windows.Count > Count Then Exit Do
Loop While Wait.Waiting
Browser = Windows(Count)
Browser.Visible = (WindowState <> ProcessWindowStyle.Hidden)
Return Browser
End Function

Resources