Getting the windows account name associated with the MSIE handle/browser

Started by hdsouza, November 15, 2014, 10:07:53 AM

Previous topic - Next topic

hdsouza

Hi,
I am launching several IE browsers, each from different winbatch programs. Each winbach program (child program) is RUN from inside its specific windows account. (The windows account is automatically created as required  by a parent winbatch program)

The child program opens a browser with
RunShell("%IE_Prgpath%\iexplore", "google.com", Prg_path, @NORMAL, @GETPROCID)
I could have used  msie = ObjectOpen("InternetExplorer.Application"), but I have found it to be very flaky hence I have no option but to use the Runshell command.

With the Runshell command I need to get a handle to the browser which I can get using the GetMSIE subloop


:GetMSIE
msie = 0
   Shell = ObjectOpen("Shell.Application")
   For x = 0 To Shell.Windows.count-1
      swc = Shell.Windows.count-1
      ErrorMode(@OFF)
      swi = Shell.Windows.item(x)
      If !swi
         ErrorMode(@CANCEL)
         Continue
      EndIf
      swif =  Shell.Windows.item(x).fullname
      If !StrIndexNC(swif, "iexplore.exe", 1, @FWDSCAN)
         ErrorMode(@CANCEL)
         Continue
      EndIf

      msie=Shell.Windows.item(x)
      URL = msie.LocationURL
      URL_Valid = StrIndexNC(URL, "internet explorer", 1, @FWDSCAN)
      If !URL_Valid
         ErrorMode(@CANCEL)
         Continue
      Else
         Break
      EndIf
      ErrorMode(@CANCEL)   
   Next
if msie == 0 then goto GetMSIE
Return


The Question: How can I get the "Windows account name" that is associated with the specific MSIE handle/Browser. (Often times the browser names launched by several winbatch children could be exactly the same. Hence I need to get the associated "Windows account name" ). If I can get the associated win account name I can validate it straight into the GetMSIE subloop.

Please help
Thanks



JTaylor

Assuming I understand...perhaps

username = Environment("user")

Jim

hdsouza

Actually I need the windows account name associate with the MSIE handle that i received in the code as specified above

td

There are several ways to get name of the owner of a process in WinBatch but I am not aware of any way to map between a shell browser window object and the owner of the process that the object represents. At least, not when multiple objects can have the same object properties like name and/or url. 

You may have to reconsider your approach.  You could do something like set up a communication mechanism between script processes.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

JTaylor

Okay.  Thought since the child script was running under a specific account it would return that user name.  Guess I didn't understand.

Jim

hdsouza

TD, So what are the "several ways to get name of the owner of a process in WinBatch". Can you tell me one
(Also the name and url could be the same .. but the MSIE handle returned is always unique)

td

Quote from: hdsouza on November 17, 2014, 08:19:12 AM
TD, So what are the "several ways to get name of the owner of a process in WinBatch". Can you tell me one
(Also the name and url could be the same .. but the MSIE handle returned is always unique)

Look in the Tech. Database for examples of obtaining a process id and yes, all window handle are unique for existent windows.

http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/nftechsupt.web+WinBatch/How~To+Get~ProcessID~Thread.txt

In this case you can use a Windows API call to map from the window handle to the process id and from there you may be able to use the terminal services extender to obtain the session id and session owner.

Of course the approach assumes you will not run afoul of process integrity levels which may or may not be a valid assumption.  It all depends.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

hdsouza

Quote from: JTaylor on November 17, 2014, 08:16:20 AM
Okay.  Thought since the child script was running under a specific account it would return that user name.  Guess I didn't understand.

Jim


True, But here is what is happening.
Even though a child program is launching IE from its own windows account, it is launching the browser in the same windows workspace as browsers of other children.  So inorder to identify the correct MSIE handle  that the child needs to associate with, I need to the windows account name associated with that MSIE handle.
(Also to clarify, the child program already knows the name of windows account it launched in as the parent program already supplied those details to the child by means of an input text file)

JTaylor

Not sure what you are doing but couldn't you open the browser to a temporary HTML page with the needed information as part of the url, before browsing to whatever you are doing?   You could then read the current url and extract the info you want???   You say you know the user so if there is a url with the user name you would loop through the processes checking the current URL and when you find the user name you know which process matches.

Jim

td

Another problem with the windows handle approach involves how IE is started.  If IE is started via a method that involves impersonation, you may not be able to obtain the impersonated user account associated with the IE instance as impersonation is on a per thread bases.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

hdsouza

Quote from: JTaylor on November 17, 2014, 09:23:19 AM
Not sure what you are doing but couldn't you open the browser to a temporary HTML page with the needed information as part of the url, before browsing to whatever you are doing?   You could then read the current url and extract the info you want???   You say you know the user so if there is a url with the user name you would loop through the processes checking the current URL and when you find the user name you know which process matches.

Jim

Jim, Thats what I am asking for. How do I loop through the processes to find out the user name associated with the process.
A direction would be great

JTaylor

Assuming your process allows for such a thing it is fairly simple....You already know how to retrieve the URL as that is part of your current process.   At whatever point you know the username write the html file with a name something like:

user_name = "george"
temp_htm = DirScript():user_name:"_temp.htm"
FilePut(user_name:"_temp.htm","<html><body></body></html>")

When you launch Internet explorer just navigate to the temp page first

    msie.navigate("About:Blank",0,'','','')
    msie.navigate(temp_htm)


Then at the appropriate point in your loop through the objects that you originally posted, match up the object with the user

      URL = msie.LocationURL
      If StrIndex(URL,user_name:"_temp.htm",0,@FWDSCAN) > 0 Then
        Message("HEY",msie:" goes with ":user_name)
      EndIf


Then navigate to whatever page you are supposed to be at.

Jim

hdsouza

Jim, thanks very much for the code.
This would be assuming that the url launched from one child is different another child. It is quite possible that they could be the same. in that case two children would fight over the same URL. Thats the reason why I wanted to find the windows account for the associate MSIE handle. The MSIE handle would always be unique, even when the URL and page/window name were the same
Thanks

JTaylor

That was the point of my post.   Assuming it would work in your situation, not sure what your endgame might be, the initial URL would always be unique and contain the user name so you could match the user with the browser object.  If you launched more than one browser session for the same user then you would need to add a bit more to the url to keep it unique.  After obtaining the browser object you would then proceed to the desired URL.

Jim

hdsouza

my objective was as mentioned in my very first post.. which is getting the windows account associated with the MSIE handle that the program returned

JTaylor

I know that is a step along the way but wasn't sure what the ultimate goal might be and what was allowed along way such as navigating to a different URL initially.   I assume you are interested in accomplishing more than just obtaining a browser object and matching it to a user but I could be wrong.  I obviously don't need to know that but sometimes it is helpful in making suggestions.

Jim

hdsouza

Well, once I get the webpage, I need to extract the contents of the page and analyze them for keywords. Based on the existence of specific keywords, the program would either quit the browser or modify/submit the contents. There is whole lot of programming there.

I would prefer to concentrate on the initial problem  which is getting the right msie handle.. as I mentioned earlier and in my first
Without the right MSIE HANDLE winbatch childeren could fight over the same browser.. which account for bad programming.. which is what I need to avoid

Maybe I could use task manager to co-relate the MSI handle?

JTaylor

So what I suggested won't work?    Submitting a unique URL initially which contains the user name so you can match up user and browser object?

Jim

hdsouza

Well, the problem is the parent program is submitting the URL to the child by way of an input text file. So the parent could submit the same URL to two different children with same or different tasks. Thats my predicament

I am going to research task manager, but task manager is an area i have not ventured in with winbatch, so I am not sure how to iterate through it. Even if I did manage to iterate though, would the MSIE handle that winbatch returns (as in my initial code) match what winbatch would return when iterating through task manager

td

Quote from: hdsouza on November 18, 2014, 09:07:20 AM
Well, once I get the webpage, I need to extract the contents of the page and analyze them for keywords. Based on the existence of specific keywords, the program would either quit the browser or modify/submit the contents. There is whole lot of programming there.

I would prefer to concentrate on the initial problem  which is getting the right msie handle.. as I mentioned earlier and in my first
Without the right MSIE HANDLE winbatch childeren could fight over the same browser.. which account for bad programming.. which is what I need to avoid

Maybe I could use task manager to co-relate the MSI handle?

Again, how exactly are you launching IE from scripts using different user credentials? (Assuming you are starting them with different Windows user account credentials.)  The Shell.Application object likely isn't going to even report IE processes running in a different session on newer versions of Windows.

Why not try the URL suggestion or some other form of cross process communication?
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

hdsouza

Quote from: td on November 18, 2014, 10:24:46 AM
Again, how exactly are you launching IE from scripts using different user credentials? (Assuming you are starting them with different Windows user account credentials.)  The Shell.Application object likely isn't going to even report IE processes running in a different session on newer versions of Windows.

Why not try the URL suggestion or some other form of cross process communication?

I have explicity specified how I am launching IE in my initial post:
RunShell("%IE_Prgpath%\iexplore", "google.com", Prg_path, @NORMAL, @GETPROCID)
Which specific cross process communication are you referring to ???.. All have been addressed above.. some several times

td

Quote from: hdsouza on November 18, 2014, 10:42:51 AM

I have explicity specified how I am launching IE in my initial post:
RunShell("%IE_Prgpath%\iexplore", "google.com", Prg_path, @NORMAL, @GETPROCID)

RunShell by itself does not start a script using different window user credentials. You have given no indication of the mechanism you are using to start IE using different Windows user accounts.  This is the important bit and saying you use RunShell doesn't shed much light.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

JTaylor

Sorry if I haven't been clear or am misunderstanding something...Sounds like you have everything in place that you need.   You know who the user is, you are creating a text file which you can use as you are but can also create an html file (or rename your current one, the one containing the URL, and use it for this purpose), to which you can navigate and which has the user name as part of the URL as I outlined previously.   The URL will allow you to match the browser object with the user as, I understand, you are wanting to do.  Not sure what else to add to my suggestion.


Jim

Quote from: hdsouza on November 18, 2014, 10:01:44 AM
Well, the problem is the parent program is submitting the URL to the child by way of an input text file. So the parent could submit the same URL to two different children with same or different tasks. Thats my predicament

I am going to research task manager, but task manager is an area i have not ventured in with winbatch, so I am not sure how to iterate through it. Even if I did manage to iterate though, would the MSIE handle that winbatch returns (as in my initial code) match what winbatch would return when iterating through task manager

hdsouza

Jim, Sorry for the delay in responding but I am still stuck with this project.
Yes you are right, when the child is launched, it does have knowledge of the windows account name that was used to launch the browser.
So lets say CHILD1 launched IE using windows account name MULTIUSER1
and CHILD2 launched IE using windows account name MULTIUSER2

When CHILD1 (and child2) launches IE it uses RunShell("%IE_Prgpath%\iexplore", "google.com", Prg_path, @NORMAL, @GETPROCID)
so it does not have a handle to IE.
It gets a handle to IE with

Code (winbatch) Select

:GetMSIE
msie = 0
   Shell = ObjectOpen("Shell.Application")
   For x = 0 To Shell.Windows.count-1
      swc = Shell.Windows.count-1
      ErrorMode(@OFF)
      swi = Shell.Windows.item(x)
      If !swi
         ErrorMode(@CANCEL)
         Continue
      EndIf
      swif =  Shell.Windows.item(x).fullname
      If !StrIndexNC(swif, "iexplore.exe", 1, @FWDSCAN)
         ErrorMode(@CANCEL)
         Continue
      EndIf

      msie=Shell.Windows.item(x)
      URL = msie.LocationURL
      URL_Valid = StrIndexNC(URL, "internet explorer", 1, @FWDSCAN)
      If !URL_Valid
         ErrorMode(@CANCEL)
         Continue
      Else
         Break
      EndIf
      ErrorMode(@CANCEL)   
   Next
if msie == 0 then goto GetMSIE
Return


So lets says Child1 and Child2 launch their browsers at the same time. Then Child1 would use the GetMSIE routine to get a handle to the browser (it believe it launched). But that could be the browser launched by Child1 or Child2 and not necessarily by Child1. That is my problem. 
When I iterate through the objects in the GetMSIE routine is there a way to get the windows account name associated with the particular process. If that is possible then I can correlate the browser with the windows account name and know which child should control it

Thanks

JTaylor

What I am saying is that rather than navigating to "google.com" is to have the process create a local file containing the information you need as the file name and navigate to that instead.  The following is not intended to be runnable code but hopefully demonstrates what I have said previously.
fname = Temp_Path:child1:"_":username:"_.html"
hname = "file:///":StrReplace(Temp_Path,"\","/"):child1:"_":username:"_.html"
FilePut(fname,"")
RunShell("%IE_Prgpath%\iexplore", hname, Prg_path, @NORMAL, @GETPROCID)

:getMSIE
......
     URL = msie.LocationURL

     fname = ItemExtract(-1,URL,"/")
     chk_child = ItemExtract(1,fname,"_")
     chk_user = ItemExtract(2,fname,"_")

     If chk_child == child1 Then.......
     If chk_user == username Then.......
.....
Return

hdsouza

Jim, thanks for the code.
I only used google as an example.
Yes I could put a file name with the link that the CHILD needs to navigate to. I think that is what you are suggesting correct?
Then I could use the GETMSIE loop to check if which browser navigated to that specific link.
But here is the problem: If CHILD1 and CHILD2 need to go to the same link (with different tasks to be done), then child1 would not know if the browser returned by Getmise was the one it launched.

That was the reason I was trying to get the windows account  name when I iterate in the Getmise loop


JTaylor

Again, maybe I am misunderstanding but if your URL is specific to the one launching it then there should be no confusion.  Once you grab the information from the *custom* URL then navigate to where you really want to go.  You would never launch and, initially, navigate to the same URL for child1 and child2.

Jim

hdsouza

Quote from: JTaylor on January 27, 2015, 11:21:27 AM
Again, maybe I am misunderstanding but if your URL is specific to the one launching it then there should be no confusion.  Once you grab the information from the *custom* URL then navigate to where you really want to go.  You would never launch and, initially, navigate to the same URL for child1 and child2.

Jim

Jim,
That is the problem.The URL most times is  exactly the SAME for both child1 and child2. If it were uinque to the child it would be fairly simply.  The tasks done by a child is different on the same URL, but yes the probability they could be the same is very high. Hence the reason for getting the win account name  for the specific IE.. unless there is another way around

JTaylor

Not sure how to say this any other way.   Maybe someone else will repeat it in different words?

You "create" the initial file/URL with the identifying information you need and once the script gets that information then go the URL you really want to go to, even if the eventual URL is the same URL for everyone.  By that point you have the handle you need.  I thought my example would finally make clear what I have been saying.


Jim

hdsouza

Quote from: JTaylor on January 27, 2015, 09:07:19 PM
Not sure how to say this any other way.   Maybe someone else will repeat it in different words?

You "create" the initial file/URL with the identifying information you need and once the script gets that information then go the URL you really want to go to, even if the eventual URL is the same URL for everyone.  By that point you have the handle you need.  I thought my example would finally make clear what I have been saying.


Jim

Jim, I am able to launch multiple children running together which  each child  in turn launching IE and navigate to a specific  URL . That is not the problem. The problems arises when two or more children will fight over the same browser, especially when the URL are the same, unless the child is able to distinguish its browser from the browser of another child.

I understand what you are saying as having a text file containing the unique information send to the child, but in this case distiguishing cannot be done before the fact, but after the child has launched the browser.. The only distinguishing factor I see is the windows account that launched the browser, unless you see another distinguishing factor. The URL could have been a distinguishing factor, but unfortunately its not in this case as URLs are not unique

It is difficult for someone to understand the exact problem unless its not been experienced before. That's the reason why I cut to the chase and asked if anyone knew a way to get the windows account that launched a browser after a handle to the browser was received. I have written a few other Parent-child programs running 16 children at a times although this one is different, because the URLs can be the same.
Thanks for your suggestions though

JTaylor

I obviously don't know everything you are doing but if you are launching child processes you can surely generate some unique identifier for the child process (maybe even retrieve the process id?).  If the user will only be launching one process and the confusion is between users then the user id should suffice or a combination of the two.   Either way I would think you could use that in the manner I have suggested to accomplish what you need.  When you launch the child process you should be able to devise some simple way to pass a unique identifier to the child script when it launches.

I'll bow out after this post because I feel like I am missing something because the solution seems simple to me and I'm sure everyone is tired of me repeating myself but I don't know what else to say.   Sorry if I have somehow missed the point and have wasted your time.   Maybe someone else will chime in and make it all clear.

Jim

hdsouza

If I could get somehow the windows name in the getmsie loop for the browser, that would be the "unique identifier" for the browser.
Thats what I have been asking from my very first post

JTaylor

I answered that when you first asked.   The Evironment() function will provide that information and you can then use that info as the name of an html file and navigate to it initially when lauching the browser which you can then interrogate to get the right IE handle.

Jim

hdsouza

Quote from: JTaylor on January 28, 2015, 11:44:43 AM
I answered that when you first asked.   The Evironment() function will provide that information and you can then use that info as the name of an html file and navigate to it initially when lauching the browser which you can then interrogate to get the right IE handle.

Jim

Correct.... and I had had replied at the time... "Also to clarify, the child program already knows the name of windows account it launched in as the parent program already supplied those details to the child by means of an input text file"

But you are missing the point. Here is the thing: when the child1 which is launched in win account multiuser1 launches a browser with the RUNSHELL command and then uses the getmsie loop to get a handle to the browser it could return the browser of child2 which is located in windows account multiuser2.  Each child may be running in different windows accounts, but they are still running on the same computer system. if you believe that child1 will return the browser contained in its own windows account, that not true. It could return a handle to the browser of child 3 child 4 .. etc etc. That's why I keep repeating myself that the we need to get the windows account name associated with a browser handle that the child returned.  Then we can co-relate that windows account name to the value returned by Evironment() function





JTaylor

I don't know what else to tell you.  I am reasonably sure I understand what you are wanting to do and provided pseudo-code to accomplish *exactly* what you want and explained it numerous times but it is like you aren't even reading my posts.  As I said before, maybe someone else will chime in because it is apparent that my explanations are accomplishing nothing.

I guess it would be informative for you to explain to me what I have suggested you do.  Maybe we can find the disconnect in that fashion.


Jim