質問

I've got code using UIAutomation that works find in a console app, but I need it to run as a service. This service is responsible for making sure 3 exes are running on a given machine and that they are configured correctly. There is no COM or .net entry points to the exe which is written in C++.

var k = Process.GetProcessesByName("genericEXE");
                foreach (var win in k)
                {
                    List<string> scol = new List<string>();

                    AutomationElement cpc = AutomationElement.RootElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ProcessIdProperty, win.Id));
                    if (cpc == null)
                        continue;
                    WalkEnabledElements(cpc, scol);
                    if (scol.Contains("COM1") && scol.Contains("COM2") && scol.Contains("COM3") && scol.Contains("COM4") && scol.Contains("COM5"))
                        foundCom1 = true;
                    if (scol.Contains("COM6") && scol.Contains("COM7") && scol.Contains("COM8") && scol.Contains("COM9") && scol.Contains("COM10"))
                        foundCom6 = true;
                    if (scol.Contains("COM11") && scol.Contains("COM12") && scol.Contains("COM13") && scol.Contains("COM14") && scol.Contains("COM15"))
                        foundCom11 = true;


                }



static void WalkEnabledElements(AutomationElement rootElement, List<string> col)
        {
            TreeWalker walker = new TreeWalker(Condition.TrueCondition);
            AutomationElement elementNode = walker.GetFirstChild(rootElement);
            while (elementNode != null)
            {
                Console.WriteLine(elementNode.Current.Name);
                col.Add(elementNode.Current.Name);
                WalkEnabledElements(elementNode, col);
                elementNode = walker.GetNextSibling(elementNode);
            }
        }

I've tried running the service as the same user that is logged on while this is running, tried running as local service w/ the interact w/ desktop bit turned on. I never get an AutomationElement back from the

AutomationElement cpc = AutomationElement.RootElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ProcessIdProperty, win.Id)); 

line. Anyone got an idea on what I need to do differently?

役に立ちましたか?

解決

If you're running Vista or later then for security reasons services are always created in Session 0, which is separate from any user session. You cannot share UI elements or send messages back and forth between sessions, which is probably why your automation stuff isn't working. Just because a service is running as a particular user doesn't mean that its process is running in the same session. Services must continue to run even when nobody is logged on, so they must be created in their own session.

As a workaround I think CreateProcessAsUser could be used to spawn yet another process in the user's session. You would then need to use interprocess communication (e.g. WCF over pipes) to manipulate it from your service. Sounds messy. The better option might be to forget about the service and stick with a console app.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top