Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsVB SyntaxEnterprise DevelopmentDatabase AccessControlsCOMWin APICrystal ReportDeploymentGeneralGeneral 2
Related Topics
VB.NET / ASP.NETMS SQL ServerMS AccessOther Database ProductsMore Topics ...

VB Forum / COM / March 2005



Tip: Looking for answers? Try searching our database.

Using Shell Command from a COM+ Component

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Steven Moschidis - 16 Feb 2005 09:56 GMT
Hello,
I've got a weird one.
I am using the shell command from a COM+ component to call an
application that carries out a task asynchronously.
Everything works apart from one minor detail, which will become major
soon as the next evolution of the app requires it to run batches of
tasks (i.e. has to be visible):  the application is not visible
regardless of the setting I use in the shell command (I have tried all
of them and nothing works).

I have also tried playing around with the form's settings (startup
position etc.) to no avail.

I have tried calling an app that is windows default (eg. notepad) and
the behaviour was the same:  the app could be found under the processes
tab of the task manager, but could not be seen.

This has obviously some connection with the fact that I am calling it
from a COM+ component, but I have no idea why this is happening. I spent
the whole day yesterday looking through help files, msdn and newsgroups,
but could not find anything.

I would really appreciate any comments anyone might have on this subject.

Thanks in advance for your time and help,
Steven Moschidis
Steven Moschidis - 02 Mar 2005 15:44 GMT
Can anyone help me with this?
Should I try a different newsgroup?
Any suggestions?

Steven

> Hello,
> I've got a weird one.
[quoted text clipped - 22 lines]
> Thanks in advance for your time and help,
> Steven Moschidis
Tony Proctor - 02 Mar 2005 18:03 GMT
I believe it's all to do with "window stations" Steven. Processes connect to
a "window station". The window station associated with the interactive user
can receive input, but others (e.g. for Windows Services) may be
non-interactive. I don't really know a lot about this area (except that I
had to once write a bit of code to enable a common module to determine
whether it was connected to an interactive windows station), so all I can do
is recommend you read up on this in MSDN or on the Web.

P.S. let us know if you find a solution :-)

       Tony Proctor

> Can anyone help me with this?
> Should I try a different newsgroup?
[quoted text clipped - 28 lines]
> > Thanks in advance for your time and help,
> > Steven Moschidis
Steven Moschidis - 04 Mar 2005 17:04 GMT
Dear Tony,
Thank you so much for the hint about window stations. I had no idea that
something like that existed although now that I have read up on them it
makes absolute sense for such a system to be in effect.

I have been tinkering around with a test application (only has code for
the Window Stations stuff) that I call through the same COM+ component
on the same machine.
The future is looking very bleak as I am trying to marry the worlds of
VB and VC++ and it's not going very well.
I will attach my code in hope that someone (maybe you Tony) will be able
to make any comments.
This is new territory for me and I have not fully understood how the low
 level distinction of a process and thread in VC++ can be reflected in
VB to take full advantage of the functions that deal with Window Stations.
The theory is briefly (merging on adequately) described at:
http://msdn.microsoft.com/library/en-us/dllproc/base/window_station_and_desktop_
functions.asp


Looking forward to hearing from you!

My code so far (the fso stuff is for error logging):

'API function declarations
Public Declare Function SetProcessWindowStation Lib "user32" (ByVal
hWinSta As Long) As Long
Public Declare Function OpenWindowStation Lib "user32" Alias
"OpenWindowStationA" (ByVal lpszWinSta As String, ByVal fInherit As
Long, ByVal dwDesiredAccess As Long) As Long
Public Declare Function OpenInputDesktop Lib "user32" (ByVal dwFlags As
Long, ByVal fInherit As Long, ByVal dwDesiredAccess As Long) As Long
Public Declare Function SetThreadDesktop Lib "user32" (ByVal hDesktop As
Long) As Long

'The window station we wish to assign to the application
Public Const INTERACTIVE_WINDOW_STATION = "Winsta0"

'ACCESS_MASK values
Public Const MAXIMUM_ALLOWED = &H2000000
Public Const GENERIC_ALL = &H10000000
Public Const GENERIC_READ_AND_WRITE = &HC0000000

'Handle to the window station
Dim hndWindowStation As Long

'Handle to the desktop
Dim hndDesktop As Long

Sub Main()
    Dim lngReturn As Integer
    Dim fso As New FileSystemObject, txt As TextStream

    hndWindowStation = OpenWindowStation(INTERACTIVE_WINDOW_STATION, 0,
GENERIC_READ_AND_WRITE)

    If IsNull(hndWindowStation) Then
        Set txt = fso.CreateTextFile(App.Path & "\log.log", True, False)
        txt.WriteLine ("Window Station Handle IS NULL")
        txt.Close
        Set txt = Nothing

        End
    Else
        lngReturn = SetProcessWindowStation(hndWindowStation)

        If lngReturn = 0 Then
            Set txt = fso.CreateTextFile(App.Path & "\log.log", True,
False)
            txt.WriteLine ("SetProcessWindowStation " & Err.LastDllError)
            txt.Close
            Set txt = Nothing

            End
        End If

        hndDesktop = OpenInputDesktop(0, 0, GENERIC_READ_AND_WRITE)

        If IsNull(hndDesktop) Then
            Set txt = fso.CreateTextFile(App.Path & "\log.log", True,
False)
            txt.WriteLine ("Desktop Handle IS NULL")
            txt.Close
            Set txt = Nothing

            End
        Else
            lngReturn = SetThreadDesktop(hndDesktop)

            If lngReturn = 0 Then
                Set txt = fso.CreateTextFile(App.Path & "\log.log",
True, False)
                txt.WriteLine ("SetThreadDesktop " & Err.LastDllError)
                txt.Close
                Set txt = Nothing

                End
            End If
        End If
    End If

    Set fso = Nothing

    Load Form1
End Sub

> I believe it's all to do with "window stations" Steven. Processes connect to
> a "window station". The window station associated with the interactive user
[quoted text clipped - 42 lines]
>>>Thanks in advance for your time and help,
>>>Steven Moschidis
Steven Moschidis - 17 Mar 2005 11:32 GMT
Hello again!
I've done it! I don't believe it, but I have actually made it work...
Explaining how I came about the solution would probably require a lot of
time and space, but I can describe the solution itself (or what worked
for me, I should say...) (I will not attach the code as it is too long,
but if anyone is having the same problem then please feel free to
contact me and I will email them the code!)

Please note that the account I used for the following solution had local
admin rights on the server. I have not yet tested it with another user
type (e.g. power user) and I am a bit hesitant to do so in case I break
it...

So here we go.
When I first encountered the problem all I was doing was calling the
Shell command from within the COM+ component and expected it to work.
I had no idea of what actually went on in the background just by me
calling Shell.

You must have a user account that must have local admin rights, because
we are going to use the "CreateProcessWithLogonW" API call to call the
executable.
You have to then assign the correct rights to the user so that the user
can have access to the Interactive Window Station and Default Desktop of
that window station.
This is done by using the following:
--get a handle to the interactive window station  (using OpenWindowStation)
--get the old DACL (Discretionary Access Control List) information from
    the window station   (using GetSecurityInfo)
--build an EXPLICIT_STRUCTURE structure that allows the user full access
to the window station   (using BuildExplicitAccessWithName)
--merge the old DACL and new DACL    (using SetEntriesInAcl)
--assign the newly formed DACL to the window station   (SetSecurityInfo)
[make sure you free all the handles and memory using the functions
indicated at the function specifications on MSDN]

Once this was done all I had to do was start the executable:
--populate the STARTUPINFO structure with the right values
--call CreateProcessWithLogonW

The MSDN articles I used as a starting point were:
How To Start a Process as Another User from Visual Basic --
http://support.microsoft.com/default.aspx?scid=kb;en-us;285879

How To Use High-Level Access Control APIs from Visual Basic --
http://support.microsoft.com/kb/295004/EN-US/

Window Stations and Desktops --
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/wi
ndow_stations_and_desktops.asp


Converting C Declarations to Visual Basic --
http://msdn.microsoft.com/library/en-us/vbcon98/html/vbconconvertingcdeclaration
stovisualbasic.asp?frame=true


[this last one proved invaluable as all the processes and structures and
variables used had to be ported from Win32 API. I used no VB code apart
from the error handling]

In closing I would like to thank you Tony once more for opening the door
to a side of Windows I never knew anything about, but now I can
confidently say that I still don't know much! ;) But at least I have got
a vague idea and basic understanding of what goes on with window
stations and desktops! Cheers!

Kind Regards,
Steven Moschidis
Tony Proctor - 18 Mar 2005 12:09 GMT
Thanks for the update Steven. There's a lot of useful stuff in this

       Tony Proctor

> Hello again!
> I've done it! I don't believe it, but I have actually made it work...
[quoted text clipped - 44 lines]
>
> Window Stations and Desktops --

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/wi
ndow_stations_and_desktops.asp


> Converting C Declarations to Visual Basic --

http://msdn.microsoft.com/library/en-us/vbcon98/html/vbconconvertingcdeclaration
stovisualbasic.asp?frame=true


> [this last one proved invaluable as all the processes and structures and
> variables used had to be ported from Win32 API. I used no VB code apart
[quoted text clipped - 8 lines]
> Kind Regards,
> Steven Moschidis
Steven Moschidis - 22 Mar 2005 13:07 GMT
I have tried it with a normal member of the Domain User group (the user
we are using to run the COM+ on our web servers) and it worked fine!

> Hello again!
> I've done it! I don't believe it, but I have actually made it work...
[quoted text clipped - 61 lines]
> Kind Regards,
> Steven Moschidis
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.