COMate - control COM objects via automation - OBSOLETE!

Developed or developing a new product in PureBasic? Tell the world about it.
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

Sucess !!!! (Thanks to Kiffi and srod with that one little critical piece this morning - the UpdateSearcher\GetObjectProperty("Search('IsInstalled=1 and Type=$0027Software$0027'")") part - Thanks :) )

It works here on Vista SP1 and should work on XP also (with the latest Windows Update client installed). This only gets the updates that have been installed by Windows Update on the computer already, and gets the updates that are available on Windows Update presently. Uses the Windows Update API (http://msdn.microsoft.com/en-us/library ... S.85).aspx) and of course COMate.

Code: Select all

Procedure Updates_OnLocal_Machine_infox() ; gets updates that have been installed on computer by Windows Update

Protected updateSession.COMateObject
Protected updateSearcher.COMateObject
Protected SearchResult.COMateObject
Protected update.COMateObject
Protected objUpdates.COMateObject
Protected objItem.COMateObject

updateSession = COMate_CreateObject("Microsoft.Update.Session")
updateSearcher = updateSession\GetObjectProperty("CreateupdateSearcher()")

Debug "Searching for updates from Windows Update already installed on computer..." + #CRLF$

SearchResult = UpdateSearcher\GetObjectProperty("Search('IsInstalled=1 and Type=$0027Software$0027')")
objUpdates = searchResult\GetObjectProperty("Updates()")
count = objUpdates\GetIntegerProperty("Count()") - 1

For I = 0 To count

  update = searchResult\GetObjectProperty("Updates()")
  objItem = update\GetObjectProperty("Item('" + Str(I) + "')")
  Debug Str(I + 1) + " >>>   " + objItem\GetStringProperty("Title")

Next

EndProcedure

Procedure Updates_Avail_WinUpdate_info() ; gets updates available on Windows Update

Protected updateSession.COMateObject
Protected updateSearcher.COMateObject
Protected SearchResult.COMateObject
Protected update.COMateObject
Protected objUpdates.COMateObject
Protected objItem.COMateObject

updateSession = COMate_CreateObject("Microsoft.Update.Session")
updateSearcher = updateSession\GetObjectProperty("CreateupdateSearcher()")

Debug "Searching for updates avaliable from Windows Update..." + #CRLF$

SearchResult = UpdateSearcher\GetObjectProperty("Search('IsInstalled=0 and Type=$0027Software$0027')")
objUpdates = searchResult\GetObjectProperty("Updates()")
count = objUpdates\GetIntegerProperty("Count()") - 1

For I = 0 To count

  update = searchResult\GetObjectProperty("Updates()")
  objItem = update\GetObjectProperty("Item('" + Str(I) + "')")
  Debug Str(I + 1) + " >>>   " + objItem\GetStringProperty("Title")

Next

EndProcedure
NOTE: The only difference between the above two procedures is the 'IsInstalled=' value. 'IsInstalled=0 is for getting updates available on Windows Update and 'IsInstalled=1 is for getting updates that have been installed on the computer thru Windows Update. You could do away with one procedure and just have a 1 or 0 sent to to the procedure when you call it > Updates_Machine_infox(winupdate_local.i). I just did it this way because i'm using them in different places for dedicated purposes for expansion later.

In addition, to get updates and hot fixes that have been installed manually (not thru Windows Update), I got some code for that too that i posted previously but here it is again:

(Note: the Win32_QuickFixEngineering class does not get updates installed thru Windows Updates)

Code: Select all

Procedure QFE_Info()

Define.COMateObject objWMIService, QFEInfo
colQFEInfo.COMateEnumObject
strComputer.s = "." 

objWMIService = COMate_GetObject("winmgmts:\\" + strComputer + "\root\cimv2", "") 
If objWMIService
  colQFEInfo = objWMIService\CreateEnumeration("ExecQuery('Select * from Win32_QuickFixEngineering')")
  
  If colQFEInfo
    QFEInfo = colQFEInfo\GetNextObject()
    While QFEInfo
      x = x + 1
      id$ = Str(x)
      QFE_Caption$ = QFEInfo\GetStringProperty("Caption")
      QFE_Name$ = QFEInfo\GetStringProperty("Name")
      QFE_Description$ = QFEInfo\GetStringProperty("Description")
      QFE_FixComments$ = QFEInfo\GetStringProperty("FixComments")
      QFE_HotFixID$ = QFEInfo\GetStringProperty("HotFixID")
      QFE_ServicePackInEffect$ = QFEInfo\GetStringProperty("ServicePackInEffect")
      QFE_InstallDate$ = UTCDateToDateString(QFEInfo\GetStringProperty("InstallDate"), 0)
      QFE_InstalledBy$ = QFEInfo\GetStringProperty("InstalledBy")
      
      Debug id$ + "  Caption = " + "  " + QFE_Caption$
      Debug id$ + "  Name = " + "  " + QFE_Name$                  
      Debug id$ + "  Description = " + "  " + QFE_Description$
      Debug id$ + "  Fix Comments = " + "   " + QFE_FixComments$
      Debug id$ + "  Hot Fix ID = " + "  " + QFE_HotFixID$
      Debug id$ + "  Install Date = " + "  " + QFE_InstallDate$
      Debug id$ + "  Installed By = " + "  " + QFE_InstalledBy$
      Debug id$ + "  Service Pack In Effect = " + "  " + QFE_ServicePackInEffect$
      If QFE_HotFixID$ = "{1DCBF7A7-7735-433B-BAB6-D0194490A38C}"
      Debug id$ + "  Special Note = " + "  This item is associated with Microsoft Silverlight or other MicroSoft products"
      EndIf
      Debug "========================"
      
      QFEInfo\Release()
      QFEInfo = colQFEInfo\GetNextObject()
    Wend
    colQFEInfo\Release()
  EndIf
  objWMIService\Release()
  Else
      MessageRequester("Error", "QFEInfo")  
EndIf

EndProcedure
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

SFSxOI you are a machine! :)
I may look like a mule, but I'm not a complete ass.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

Hello it's me :D

This is the day of the stupid question :D

I have always the problem with my IE and HTTPS "Acces denied" :cry:
And if i use the WebGadget in the same adress that's works fine :shock:

Then i say to me, perhaps i have bad managing the OBJECT :roll:

But the problem, it's i can't view the value of all the object, when my mouse is other the object for all of your nices specials variables.
HTTPObject, DocumentDispatch, Script

Then ATTENTION !!! vlouvlou vlouvlouvlouvlou roll of drum

This is the question of the black day :oops:

Have you a way to see the value of all this variable ?? :roll:
ImageThe happiness is a road...
Not a destination
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

OK, got another one I don't understand:

http://msdn.microsoft.com/en-us/library ... S.85).aspx

Code: Select all

Debug "Creating collection of updates to download:"

objCollection = COMate_CreateObject("Microsoft.Update.UpdateColl")
objSearcherColl = COMate_CreateObject("Microsoft.Update.Searcher")

objResultsColl = objSearcherColl\GetObjectProperty("Search('IsInstalled=0 and Type=$0027Software$0027')")

colUpdatesColl = objResultsColl\GetObjectProperty("Updates()")
objCountColl = colUpdatesColl\GetIntegerProperty("Count()")

For I = 0 To objCountColl - 1
    
    colUpdateColl = objResultsColl\GetObjectProperty("Updates()")
    objItemColl = colUpdateColl\GetObjectProperty("Item('" + Str(I) + "')")
    Debug Str(I + 1) + "> adding: " + objItemColl\GetStringProperty("Title")
    ;Debug COMate_GetLastErrorDescription()
;     ; ////////good to here/////////
     ;objCollection.Add(colUpdates.Item(0))
     objUpdatesToDownloadColl = objCollection\GetObjectProperty("Add( < this - objItemColl - should go here but can't get to work> )")
     Debug COMate_GetLastErrorDescription()

Next
In the " objCollection\GetObjectProperty("Add" < its supposed to take this: An IUpdate interface to be added to the collection. The parameters are this:

[in] IUpdate *value, < An IUpdate interface to be added to the collection
[out] long *retval

No matter what I pass to it I still get a "Type mismatch in the method parameters." error (per 'COMate_GetLastErrorDescription()'). Everything else is good except for that and the value its supposed to accept is objItemColl. What am I doing wrong here to keep getting a type mismatch. I know what the type mismatch implies but i just can't get it straightened out.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Does the following not work ?

Code: Select all

objUpdatesToDownloadColl = objCollection\GetObjectProperty("Add(" + str(objItemColl) + " as COMateobject)")
If not then we can try replacing

Code: Select all

objItemColl = colUpdateColl\GetObjectProperty("Item('" + Str(I) + "')") 
with

Code: Select all

objItemColl = colUpdateColl\GetObjectProperty("Item('" + Str(I) + "')", #VT_UNKNOWN) 
in order to access the iUpdate interface directly and pass that off to the get_Add property.


**EDIT : Hang on, according to MSDN, the Add property is in fact an integer property not an object one!

Try :

Code: Select all

index = objCollection\GetIntegerProperty("Add(" + str(objItemColl) + " as COMateobject)") 
Last edited by srod on Thu Mar 12, 2009 12:30 pm, edited 2 times in total.
I may look like a mule, but I'm not a complete ass.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

Hello SROD and SFSx01

Excuse me to disturb you, with my little and simple question (but for you obviously) between your great CODE :oops:

I think, that my problem, is bad declaration of COMATE variable :roll:

Kiffi ......have say to me for have my COMATE variable GLOBAL, that i must be replace this line

Code: Select all

Define.COMateObject WebObject 
by

Code: Select all

Global HTTPObject.COMateObject 
Like this my variable is GLOBAL
It's the good way ???? :roll:

And for my question above :cry:
Have you a way to see the value of variable object HTTPObject, DocumentDispatch, Script like when i see the value of other variable with the debugger and pass the mouse pointer over it ???
Last edited by Kwai chang caine on Thu Mar 12, 2009 12:29 pm, edited 1 time in total.
ImageThe happiness is a road...
Not a destination
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Have you a way to see the value of variable object HTTPObject, DocumentDispatch, Script like when i see the value of other variable with the debugger and pass the mouse pointer over it ???
Probably not. Why not just use a Debug statement?
I may look like a mule, but I'm not a complete ass.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

It's just for know it's a simple way exist :roll:

Never mind, i think that if the condition it's true.....

Code: Select all

If HTTPObject 
Then it's ok :D

I have found the problem how the webgadget works and not the IE

I use this procedure

Code: Select all

Procedure OuvreClientWeb(Url.s, Client = #IEExplorer)
  
 If Client = #WebGadget 
  
  If IsGadget(Client)
  
   HTTPObject = COMate_WrapCOMObject(GetWindowLong_(GadgetID(Client), #GWL_USERDATA)) 
   SetGadgetText(Client, Url)
   LoopWait()   
    
  Else
   
   MessageRequester(NomLogiciel + VersionLogiciel, "Le WebGadget " + Str(Client) + " n'éxiste pas.")
   
  EndIf 
   
 ElseIf #IEExplorer
   
  HTTPObject = COMate_CreateObject("InternetExplorer.Application") 
  
  If HTTPObject 
   
   HTTPObject\SetProperty("Visible= #True") 
   HTTPObject\invoke("Navigate('" + Url + "')") 
    
   While Status$ <> "Terminé"
    Status$ = HTTPObject\GetStringProperty("StatusText") 
    Delay(10)
   Wend 
   
   Delay(1000)
   
  EndIf 
  
 EndIf 

EndProcedure
For use the same code in IE or in a webgadget.
But i have the feel that my variable HTTPObject is not GLOBAL

I have put this

Code: Select all

Global HTTPObject.COMateObject 
If i open Webgadget first, that's works and when i open IE after that's works too.

But if i open IE first.....that's don't works
Like if my variable is not initialised...
But it's funny because the "If HTTPObject" is true :shock:

What's wrong at your mean ???
ImageThe happiness is a road...
Not a destination
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

I did not try this one:

Code: Select all

objUpdatesToDownloadColl = objCollection\GetObjectProperty("Add(" + str(objItemColl) + " as COMateobject)")
I'll give it a go. I did try a variation of it but without the as COMateobject at the end. I'll give it a whirl with the as COMateobject and see what happens.

the rest i had tried already, even the integer one, and still the same issue. I originally thought it was an integer too but with the interger one you get a different error that the object/method doesn't support it. For the first four hours of tearing my hair out i thought that i had some sort of spelling mistake or an extra character somewhere or something and retyped everything one character at a time a few times.
Last edited by SFSxOI on Thu Mar 12, 2009 12:53 pm, edited 1 time in total.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Yes that makes sense that you would have gotten a different error in this situation.

I do think that the GetIntegerProperty() call together with the " as COMateObject" will be the correct one.
I may look like a mule, but I'm not a complete ass.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

I do think that the GetIntegerProperty() call together with the " as COMateObject" will be the correct one.
Ok...but even, it's the contrary, if i open only IE the first time, that's don't works :shock:
The more funny, it's that i must open in the webgadget first, for that the IE works :shock:

Like if your procedure "COMate_WrapCOMObject" is better that the procedure "COMate_CreateObject" :shock:
ImageThe happiness is a road...
Not a destination
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Kwaï chang caïne wrote:
I do think that the GetIntegerProperty() call together with the " as COMateObject" will be the correct one.
Ok...but even, it's the contrary, if i open only IE the first time, that's don't works :shock:
The more funny, it's that i must open in the webgadget first, for that the IE works :shock:

Like if your procedure "COMate_WrapCOMObject" is better that the procedure "COMate_CreateObject" :shock:
I was talking to SFSxOI! :)

Kwai, you will need to post some code showing the problem.
I may look like a mule, but I'm not a complete ass.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

I was talking to SFSxOI!
Ohhh excuse me SROD and SFSx01
I'm always too much excited :oops:

The problem is not common :shock:
And it's difficult to test for you, because, it's an internal site of my job.

At the beginning, i believe it's the problem of HTTPS
Then i have try with EBay because it is an HTTPS site
And no with EBay that's works in the two method :shock:

If i try the first method, that's works fine.
And if i try the second method with exactly the same parameter, IE don't works
You have say to me, the other day, that it's an error "access denied" who return :shock:

So my question is :
Why the webgadget is better that the IE
Why the webgadget have right for access and not the IE

I have think that is because, perhaps it's not the same object connexion
One is "COMate_WrapCOMObject" and other is "COMate_CreateObject"
And perhaps you don't use the same command :roll:

Code: Select all

IncludeFile "COMate.pbi"

Enumeration
  
 #FormWeb
 #WebGadget
 #IEExplorer
 
EndEnumeration

Define.COMateObject WebObject 
Global WebObjectWait.COMateObject
Global HTTPObject.COMateObject 

Procedure.i ExecuteJavaScript(Command$)

 Protected DocumentDispatch.COMateObject, Script.COMateObject 
 Protected Result 

 If HTTPObject 
 
  DocumentDispatch = HTTPObject\GetObjectProperty("Document") 
  
  If DocumentDispatch 
    Script = DocumentDispatch\GetObjectProperty("script") 
    
    If Script 
     Result = Script\Invoke("eval('" + command$ + "')") 
     Script\release() 
    EndIf  
    
    DocumentDispatch\Release() 
  
  EndIf 
    
 EndIf 
 
 ProcedureReturn Result 
 
EndProcedure 
 
Procedure LoopWait()
 
 WebObjectWait = COMate_WrapCOMObject(GetWindowLong_(GadgetID(#WebGadget), #GWL_USERDATA)) 
 Status = - 1 
 
 If WebObjectWait
 
  While Status 
    While WindowEvent():Delay(1):Wend 
    Status = WebObjectWait\GetIntegerProperty("Busy") 
  Wend 
 
  WebObjectWait\Release() 
 
 EndIf 
 
EndProcedure

Procedure OuvreClientWeb(Url.s, Client = #IEExplorer)
  
 If Client = #WebGadget 
  
  If IsGadget(Client)
  
   HTTPObject = COMate_WrapCOMObject(GetWindowLong_(GadgetID(Client), #GWL_USERDATA)) 
   SetGadgetText(Client, Url)
   LoopWait()   
   
  EndIf 
   
 ElseIf #IEExplorer
   
  HTTPObject = COMate_CreateObject("InternetExplorer.Application") 
  
  If HTTPObject 
   
   HTTPObject\SetProperty("Visible= #True") 
   HTTPObject\invoke("Navigate('" + Url + "')") 
    
   While Status$ <> "Terminé"
    Status$ = HTTPObject\GetStringProperty("StatusText") 
    Delay(10)
   Wend 
   
   Delay(1000)
   
  EndIf 
  
 EndIf 

EndProcedure

Procedure EcrisDansChamp(NomElement.s, Texte.s)
 
 ExecuteJavaScript("document.all." + NomElement + ".value=" + Chr(34) + Texte + Chr(34)) 
     
EndProcedure


OpenWindow(#FormWeb, 0, 0, 800, 600, "", #PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_ScreenCentered) 
WebGadget(#WebGadget, 10, 10, WindowWidth(#FormWeb) - 20, WindowHeight(#FormWeb) - 60, "")

; First method with webgadget
OuvreClientWeb("https://SiteInternal/index.jsp", #WebGadget)
EcrisDansChamp("name", "xxxxxxxxxx") 
EcrisDansChamp("pass", "xxx")  

; Second method with IE client
; OuvreClientWeb("https://SiteInternal/index.jsp", #IEExplorer)
; EcrisDansChamp("name", "xxxxx") 
; EcrisDansChamp("pass", "xxxx")  

   
Repeat  
 Evenement = WaitWindowEvent() 
Until Evenement = #PB_Event_CloseWindow

HTTPObject\Release() 
End
ImageThe happiness is a road...
Not a destination
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

Furthermore i have see two things

It's the same problem with all the site of my job
If i open it in WebGadget that's done
And with IE not :cry:

I have modify the Script parameter in IE for see if it's a problem of script.
But if i modify this parameter .....the WebGadget don't works too :cry:

Then i think that the parameter modify also the WebGadget.
Normal, because, it's the same motor who is used.

But the most strange.....it's, why, if i open with the WebGadget, and AFTER, without close the WebGadget the IE works fine ???? :shock:
It's the cherry on the cake no ???? :?

I believe it's like the webgadget open the right....and the IE can after keep the JAVASCRIPT :roll:
ImageThe happiness is a road...
Not a destination
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Post by ricardo »

Kwaï chang caïne wrote:
I use this procedure

Code: Select all

Procedure OuvreClientWeb(Url.s, Client = #IEExplorer)
  
 If Client = #WebGadget 
  
  If IsGadget(Client)
  
   HTTPObject = COMate_WrapCOMObject(GetWindowLong_(GadgetID(Client), #GWL_USERDATA)) 
   SetGadgetText(Client, Url)
   LoopWait()   
    
  Else
   
   MessageRequester(NomLogiciel + VersionLogiciel, "Le WebGadget " + Str(Client) + " n'éxiste pas.")
   
  EndIf 
   
 ElseIf #IEExplorer
   
  HTTPObject = COMate_CreateObject("InternetExplorer.Application") 
  
  If HTTPObject 
   
   HTTPObject\SetProperty("Visible= #True") 
   HTTPObject\invoke("Navigate('" + Url + "')") 
    
   While Status$ <> "Terminé"
    Status$ = HTTPObject\GetStringProperty("StatusText") 
    Delay(10)
   Wend 
   
   Delay(1000)
   
  EndIf 
  
 EndIf 

EndProcedure


Maybe im not understanding what do you try to achive, but if you want to send the webgadget to navigate, dont need to wrapp the webgadget.

Also you need the

protect (or define) HTTPobject..COMateObject inside the procedure i guess.
Post Reply