t4ngo / dragonfly

ARCHIVED! - Speech recognition framework allowing powerful Python-based scripting and extension of Dragon NaturallySpeaking (DNS) and Windows Speech Recognition (WSR)
GNU Lesser General Public License v3.0
364 stars 82 forks source link

Switching applications in Windows 8 #49

Open latviancoder opened 8 years ago

latviancoder commented 8 years ago

I've tried different approaches to open/switch applications in Windows 8, but none of them seem to work.

The first issue is with BringApp/StartApp. Getting following error:

Only part of a ReadProcessMemory or WriteProcessMemory request was completed.

After some googling the only suggestion i found was to install 64-bit python.

Then i tried to get at least alt-tabbing to work, but neither of these two lines work.

Mimic("press", "alt", "tab") Key("alt:down, tab, alt:up")

Do you have any ideas/suggestions?

tylercal commented 8 years ago

I believe this is because you aren't running as an administrator. You can run as an administrator or execute a shortcut to C:\Users\Default\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch

I use something like this:

if sys.getwindowsversion().build < 9200:
            Key("alt:down").execute()
            Key("tab/10:%d/10" % extras["n"]).execute()
            Key("alt:up").execute()
        else:
            count = extras["n"] - 1
            os.system(os.path.dirname(__file__) + "/switcher.lnk")
            Pause("15").execute()
            for i in range(count):
                Key("right/10").execute()
            Key("enter").execute()

As far as I can tell, sending alt-tab works just fine in windows 7 and 10.

latviancoder commented 8 years ago

Well, I completely disabled UAC, but it still didn't help. Strange.

tylercal commented 8 years ago

For the BringApp, I think you do need 64-bit python if you're running 64-bit windows.

For alt-tab unfortunately it's not a UAC thing. When I say "you aren't running as an administrator" I mean you aren't running the dragonfly program from an admin command window (start, cmd.exe, right click, "run as administrator"). If you run any program as an administrator, you'll notice commands from dragonfly don't work in that program.

That said, did you try the "Quick Launch" solution above?

I don't run windows 8 anywhere anymore, but have you tried alt-escape, windows-t, or windows-(number)?

latviancoder commented 8 years ago

Running as admin unfortunately didn't help.

I did implement your quick launch solution, but i don't understand how to use it. It seems quite random. I just want to be able to jump between two applications that I use most of the time, without specifying any numbers.

Windows-number works fine.

tylercal commented 8 years ago

Too bad about the admin, I guess that's only for letting dragonfly affect programs that are running as administrator.

With quick launch you should be able to quickly switch between 2 apps (like alt-tab does).

My specific setup was to copy the "switch between windows" shortcut to the directory with dragonfly scripts (and call it switcher.lnk) so I didn't have to depend on the file being there (you may be able to reference it directly though, I'm not sure).

Then I have a mapping from "switch app []" to the function posted above. n is optional and defaults to 1. This allows me to alt-tab anywhere from 1 to n times. If I say "switch app" without a number it changes only one program, just like pressing alt-tab once. You should try executing the "switch between windows" link directly to get an idea of how you want it to work for you.

count = extras["n"] - 1 # how many apps should I switch? If default (just one, count will be 0)
os.system(os.path.dirname(__file__) + "/switcher.lnk") # open the switcher
# wait for it to open: should default to the same program you get when 
# you press alt-tab and continue to hold the alt key after releasing the tab key
Pause("15").execute()
for i in range(count): #loop gets skipped if you are just changing 1 program
  Key("right/10").execute() # otherwise each of these is like a repeated press of the tab key with alt depressed
Key("enter").execute() # bring the selected program to the foreground

You can add longer Pause actions to see each of these steps executing in slow motion.

latviancoder commented 8 years ago

Yeah I understood how it should work. but..

When three programs are opened and I say "switch app", it jumps to Program 2 as expected. But saying "switch app" again suddenly opens Program 3. After that saying it again any number of times doesn't switch anything, it just stays on program 3.

tylercal commented 8 years ago

Looking back in my git history, my original rule when I was running windows 8, looks like this:

class SwitchRule(CompoundRule):
    spec = "switch app [<n>]"
    extras = [
        IntegerRef("n", 1, 9),  # Times to repeat the sequence.
    ]
    defaults = {
        "n": 1,
    }

    def _process_recognition(self, node, extras):
        count = extras["n"] - 1
        os.system(os.path.dirname(__file__) + "/switcher.lnk")
        Pause("15").execute()
        for i in range(count):
            Key("right/10").execute()
        Key("enter").execute()

And it did work as expected.

What happens if you have 2 explorer windows both open to C:\Users\Default\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch and manually execute the switch link back and forth between the two? Does that work as expected?

latviancoder commented 8 years ago

This is what mine looks like now

class SwitchApplicationsRule(CompoundRule):
    spec = "muzzle"

    def _process_recognition(self, node, extras):

        os.system('"C:\Users\Default\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\switcher.lnk"')
        Pause("150").execute()
        Key("right/100").execute()
        Key("enter").execute()

Switching between two windows manually does work as expected, yes.

tylercal commented 8 years ago

Your code looks like it should be working as expected.

Is it possible that there is something about the windows you're trying to switch between is causing the problem? If you use dragonfly to switch between the two explorer windows does it also fail?

When I had windows 8, it did work correctly for me. It's possible some security patch since then has broken it again. Another recommendation would be to explore the many posts in the autoit community on the subject (they are much larger than us)- google: autoit alt tab windows 8

If you find a solution you like there, you can compile the autoit script into an exe that you can call from dragonfly in the same way we're calling switcher.lnk