I have an app that sometimes dynamically adds and removes entries from the start menu (and the Desktop), by placing shortcuts (created with WshShellClass) in the start menu folder (Environment.SpecialFolder.StartMenu). If any such changes occur, I already notify the shell of changes using SHChangeNotify, as described here. Specifically:
private static void _RefreshWindowsDesktop()
{
// http://stackoverflow.com/a/647286/1600
NativeMethods.SHChangeNotify(NativeMethods.HChangeNotifyEventID.SHCNE_ASSOCCHANGED,
NativeMethods.HChangeNotifyFlags.SHCNF_FLUSH,
IntPtr.Zero, IntPtr.Zero);
}
However, on Windows 10, Start Menu search frequently breaks (I've never seen this behavior in Windows Vista or 7), where a new shortcut often doesn't show up for days, and in turn, an old shortcut that has been deleted days ago still shows up as a "search result". This is presumably due to changes to make modern apps appear in the Start Menu alongside classic desktop apps, but I'm not sure; online guides to that effect frankly strike me as voodoo.
Worse, when invoking that shortcut, Windows 10 just does nothing — there's no error indicating that the shortcut points nowhere (because it doesn't exist), nor does Windows learn and remove it afterwards.
So, my hope is there's a method akin SHChangeNotify to explicitly tell Windows 10 to invalidate or rebuild its Start Menu cache, such as asking it to reindex that particular folder, or telling it to manually add/remove an item from the index.
My app is WPF, but if a native method exists, I can detect the OS version and then conditionally invoke it. (Or even write an external Windows 10-specific UWP background app to launch if needed.)
Related
I have an application that uses a low level keyboard hook to capture the user's choice of keyboard shortcuts at a global level to activate the application's main window. Because I want to allow sometimes "odd" shortcuts, like F12 or Ctrl+Ctrl (double tap), I use the hook instead of the RegisterHotkey API function. Until Windows 8, this feature worked great. In Windows 8, some windows prevent my application from receiving the event but only while those windows are in the foreground. The Windows 8 Task Manager is one such offender.
Note that, because the problem only occurs while the offending window is in the foreground, I know that my hook is still registered with the system, just temporarily not reaching my application.
The current code base is C# Framework 4.0; however, I tested the previous code base, which was unmanaged C++ and the problem is the same.
Version of Windows is 8.1 Pro with Media Center
One thing I have not yet tried is moving the hook procedure to a separate DLL. I think I read that the low level keyboard hook procedure must be in a DLL but I have never found this to be true. Before I go to the trouble of trying that, I wanted to ask whether I am missing something easier and more obvious.
Now I understand. Although my application runs under a Windows account that is in the Administrators group, it needs to be launched with "Run as Administrator" in order to avoid being blocked by UIPI.
The solution, at least for me, is to ask a Windows 8 end user to launch my application as Administrator, if s/he wants to use "fancy" global keyboard shortcuts like the ones I mention in the question. (I also allow the user to use "simple" shortcuts, which are implemented with RegisterHotkey() instead of with WH_KEYBOARD_LL and therefore do not suffer from UIPI.)
Let me layout the scenario.
We have a 3rd party application (say, app.exe installed to C:\App). It actually cannot run directly, it needs a configuration file passed to it as an argument: "C:\App\app.exe config.ini". Everyone already has shortcuts that contain the necessary arguments.
This application supports plugins, of which we have developed a few. In order to distribute said plugins, they need to be copied to each users C:\App\Plugin\ folder, so when a change is made I have to travel around to everyone's desk and make sure the update gets applied.
This was cumbersome, so I developed an application that will scan a network folder and compare it to it's internal db of files. If there are any changes, it copies the files over to the proper destination folder.
This wasn't seamless though, as the user would have to make sure app.exe was closed - run my updater, and then rerun app.exe. So I renamed the original app.exe to app_launcher.exe, and my updater to app.exe. I modified my updater application to support arguments and pass them through to app_launcher.exe when the update was done. Once app_launcher.exe has started the updater program closes.
I should note - the above actually works.
The problem comes from users who have the app shortcut pinned to the taskbar. Once the real app finally starts it gets it's own new icon on the taskbar instead of being grouped with the original shortcut. This actually makes sense as they are technically two different applications. The users however, don't like this.
I have done some research on this, and found some 3rd party programs that can allow you to group multiple programs (Bins/Fences). I DO NOT WANT THIS.
More research revealed something called the AppUserModelID, which intrigued me. After some playing around, I got my updater to set it's own AppUserModelID. The original app.exe didn't set it's AppUserModelID (found that out via ProcessHacker), but I was able to get the updater to start it with the same ID it was using via the CreateProcess method found in kernel32.dll.
This did NOT work. The updater started under it's own pinned icon, and the original app started a new icon. I tweaked the updater to stay open until the original app was closed to see if that made a difference. This time it started under it's own pinned icon, the original app started it's own, and then the updater window switched to be grouped with the original app under the new icon. So AppUserModelID did group them together, but not how I wanted.
I am using C# for the updater application, and cannot make changes to (or have changes made to) the original app.
How can I get these applications to group under the pinned shortcut? Is it even possible?
I think I may have found a solution, though it's a bit of a hack.
The problem comes from having the final application not matching the shortcut being run.
So rather than replacing the EXE and running the real one when done, I made sure the updater application would always run before the real exe.
The only caveat is that it also runs for EVERY exe on the system (via HKCR\exefile). The first parameter is now the path to the true executable, which if it matches the application it runs the updater. Once the updater finishes or if it is any other app, it runs it.
Not an ideal solution (as it could be detected as malware), but it should work for us.
I have an application I've written for Windows 7/8 which relies heavily on the new taskbar features - jumplists, taskbar overlays, thumbnail previews, etc. Users are instructed to pin the application to get the most out of it.
Every now and then I release an update for this application and during the upgrade process, when the old EXE is removed and the new one installed, the pinned application will lose its icon -- it becomes the default generic file icon.
From what I can tell, it's a simple icon caching problem, and rebooting the machine or restarting explorer will bring the icon back.
I can have my installer ask the user to reboot the machine after each upgrade, but ideally I'd like to find a way to avoid the icon being lost in the first place. The most brutal approach which would definitely work would be to terminate explorer.exe, but that's not ideal either.
I'm using InstallShield LE for the installer, so a lot of the "hard work" is done for me, but this also limit my options. I know I can execute scripts/programs at certain points during the install though.
How can I avoid the icon being lost, or otherwise programatically force windows 7 to refresh the pinned taskbar icons?
Decided to reboot after each update.
i want to write an application, which reads under windows xp the quick launch items in the order like they are located in the taskbar,
and sets hotkeys for each of these item.
windows + 1 should start the first application
windows + 2 the second, etc.
(like in windows 7)
all of these items are found i a folder, but if i read the items of this folder, i dont get the right order of these items.
i found two solutions the get the right order - first:
in the registry an entry is found, where its saved how they are located, but not in plain text. i dont know how to read this, and cant reverse engine it.
the second:
read via winapi the items tooltip from the taskbar, so i can (if there are not items with the same name) search via the name in the quick launch folder.
the quick launch bar is just a listview (syslistview32).
via sendmessage i got it work to count the items, and start one (faking a click on this item), but how the hell can i read the tooltip?
i have googled a lot, tried everything, but i didnt get it run.
i hope you have any snippets for me, to solve this problem.
cheers
Determining the order of the items in the Quick Launch toolbar programmatically is going to be inherently fragile. There's not an API exposed for this, which means that it's subject to change in future versions of Windows, breaking your code that relied on assumptions about undocumented implementation details.
However, this is less of a problem in this specific case than it normally would be, since the Quick Launch toolbar doesn't exist anymore (or, at least, no one uses it anymore). The last version of Windows that used the Quick Launch toolbar was Vista, so if you make sure that your code is compatible with Vista and earlier, you should be fine. It won't work with newer versions anyway.
The positions of items in the Quick Launch toolbar is stored in the Registry in the following key:
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams\Desktop
You can extract the information from there, parse and interpret it, and then use it as you like. As you mention, this information isn't stored in plain text form because that would be very slow for the shell to load and parse itself. Since this is undocumented and not designed to be used by clients, they had no particular benefit in making it user (or developer) friendly. All that matters is what's most efficient for the shell, and storing the binary information from its internal structures is the obvious choice.
You will need to reverse engineer this in order for it to be useful to you. The way I'd go about it is probably by setting up a test environment with a couple of items in the Quick Launch bar in a particular order, exporting the information from the Registry, moving one of the items around, exporting the updated information from the Registry, and comparing the two exported Registry files to see what changed. Rinse and repeat as many times as necessary to deduce the pattern. (Really makes you wonder why so many developers actually do take the time to reverse-engineer undocumented aspects of Windows, doesn't it?)
The other option would be to use Spy++ to investigate the windows that implement the taskbar and its Quick Launch toolbar. I don't have a pre-Windows 7 system around, but it sounds like from the question that you've already done this and determined that the Quick Launch toolbar is implemented using a standard ListView. If you know the name of that window (and the names of its ancestor windows), you can walk through those windows to obtain a handle to the window you're interested in. And then you can determine the order of the items in the window as if it were a standard ListView in your own application.
The documentation for ListView controls is here; that should get you started in the right direction. You can get the text of one of the subitems by sending the LVM_GETITEMTEXT message.
This is probably the easier way of doing it. The same caveats apply--there is nothing keeping future versions of Windows from changing the names of those windows or the way that the taskbar is implemented, but since the only versions of Windows that have a Quick Launch toolbar have already been released (and therefore aren't likely to change), this may not be a big problem.
Then again, with the fact of the Quick Launch toolbar's obsolescence in mind, I struggle to comprehend why this endeavor is even worthy of investing developer time.
Also, even once you get this program all written and installed, consider what happens when the user adds a new item to the Quick Launch toolbar or re-arranges the existing items. How is your utility going to know that and adjust the keyboard shortcuts accordingly? What if an installer adds/removes an item from the Quick Launch toolbar?
I have an idea to write a multimotor taskbar application in c# for windows xp. So, does anyone have any information how
to put a taskbar on the second
monitor,
to make it use windows styles,
to prevent aplications running on the
second monitor to appear in default
taskbar,
so on...
Any help would be ...helpful )))
You can P/Invoke SHAppBarMessage() to create a task bar. The APPBARDATA.hWnd you'll need could simply be the Handle of a Form class. Anything goes as far as what you display.
Getting the notifications you'll need to make the task bar display active windows is going to be a whole lot more difficult. You'll need to use the global WH_SHELL hook, set by SetWindowsHookEx() to receive the notifications you'll need. You cannot set this hook in C#, it requires an unmanaged DLL that you can inject into a process. You'll find crucial help in this project.
Getting the Windows taskbar to not do its normal job is going to be impossible unless you somehow find the undocumented information you'll need. Microsoft doesn't document this for a good reason, the taskbar is an important part of the way they innovate on the Windows look-and-feel. Quite visible in Win7. They don't want any code to take a dependency on this, they'd have a near-impossible job of keeping the next version of Windows compatible. I'd have to recommend you completely disable the Windows taskbar and replace it by your own.