13

I write a small desktop application (main form) in the C# language (.net). And i want to have my application in top of the start menu (Windows 8), just like the "camtasia studio screenrecoder".

See screenshot what i want for my small application.

enter image description here

What code must i add in my application?

note: I have try to set the topMost = true, and that doesn't work.

user1731468
  • 864
  • 2
  • 9
  • 30
  • Winforms? Metro? As far as I am aware you cannot do this without messing with the shell, which is what Camtasia most likely does. Why do you want to? – KingCronus Jan 31 '13 at 15:37
  • I mean the Desktop application (like "camtasia studio screenrecoder") – user1731468 Jan 31 '13 at 15:38
  • 4
    In Windows8 desktop applications sit seperately to the new full screen start menu. Could you provide a screenshot of what you are comparing against with Studio Recorder? – KingCronus Jan 31 '13 at 15:39
  • Interesting. My suspicion is that they have done something clever using the shell. Makes sense for this application. But what application do you have that makes it worth breaking design convention? – KingCronus Jan 31 '13 at 15:52
  • want to make a similar basic screen capture. – user1731468 Jan 31 '13 at 15:56
  • even Microsoft keyboard application is showing also in top in my Windows 8 start menu – user1731468 Jan 31 '13 at 16:04

2 Answers2

6

If you want a window on top of Metro, you need it to declare accessibility. Here are the key points:

  1. The application must demand uiAccess (app.manifest)

  2. The application must assert “topmost” window positioning (either in Win32/SetWindowPos or WinForms/WPF’s “Topmost” property, programmatically or otherwise)

  3. Without making changes to the group policy setting, it must be installed to some trusted location [C:\Windows, C:\Program Files, C:\Program Files (x86)].

a. Note: If you want to be able to run it out of an arbitrary location, you must disable the security setting: “User Account Control: Only elevate UIAccess applications that are installed in secure locations”.

b. Note2: This is the same as setting HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\ValidateAdminCodeSignatures to 0

  1. Said application cannot be ran in the debugger

  2. If it’s a .NET application

a. The manifest must be embedded in a post-build step

b. The application must have “delayed signing” (meaning it cannot be ran from the built-in debugger, although you can build and attach – this is what Microsoft does)

  1. The application must be signed with a trusted certificate.

  2. Said trusted certificate must be installed to the Trusted Root Certificate Authority (this is important! It must not just simply installed)

For more info see: http://msdn.microsoft.com/en-us/library/ms726294

Radin Gospodinov
  • 2,313
  • 13
  • 14
  • 2
    I spent two hours searching for answer, and all i have found - [this article](http://blogs.microsoft.co.il/blogs/pavely/archive/2012/05/16/windows-8-topmost-vs-topmost.aspx). It seems to be a non-trivial challenge. – Anthony Feb 02 '13 at 23:40
  • @Anthony that is interesting link :) – user1731468 Feb 03 '13 at 09:59
  • (@Radin that's better than just copy & paste the 'comment') – user1731468 Feb 03 '13 at 10:00
  • Just a note, be careful with the UI control. If you invoke certain multithreaded functions you can actually cause exceptions and errors. But my question is, what is your application doing and why does it need to run on-top of `Start`? If your attempting to just update the user, you can send request to update the `Tile`. – Greg Feb 05 '13 at 22:58
  • @Greg i want to create a 'screen capture' also. But a basic version and free (great tool for screen capture of the windows metro app). That other developers can use it :) – user1731468 Feb 06 '13 at 10:09
4

In order to force your application above Metro's User-Interface you'll need to do the following:

  1. Create a Win32 Project
  2. Finish the wizard with no changes.
  3. Change the CreateWindowEXand set WS_EX_TOPMOST
  4. Go to Project.Properties and link to manifest file.
  5. Change UAC to bypass UI Protection; should be /uiAccess = "true"
  6. Build your project.
  7. Use the SignTool to sign the application.
  8. Ensure the application is stored in Program Files or Program Files (x86)
  9. Run your application.
  10. Load your Start Menu and your application should be running above Metro.

Your manifest should look like:

<trustInfo xmlns="urn:0073chemas-microsoft-com:asm.v3">
    <security>
        <requestedPrivileges>
        <requestedExecutionLevel
            level="highestAvailable"
            UIAccess="true" />
        </requestedPrivileges>
    </security>
</trustInfo>

By default it is set to false if the attribute is omitted, or a manifest doesn't exists for your assembly. With it false you will not be able to gain access to ProtectedUI.

More information on the security can be found here:

Here is a script that may work or allow modification to test UAC:

class Elevated_Rights
{

    // Token Bool:
    private bool _level = false;

    #region Constructor:

    protected Elevated_Rights()
    {
         // Invoke Method On Creation:
         Elevate();
     }

     #endregion

     public void Elevate()
     {
         // Get Identity:
         WindowsIdentity user = WindowsIdentity.GetCurrent();

         // Set Principal
         WindowsPrincipal role = new WindowsPrincipal(user);

         #region Test Operating System for UAC:

         if (Environment.OSVersion.Platform != PlatformID.Win32NT || Environment.OSVersion.Version.Major < 6)
         {
              // False:
              _level = false;
         }
         #endregion

         else
         {
              #region Test Identity Not Null:

              if (user == null)
              {
                    // False:
                    _level = false;
              }
              #endregion

              else
              {
                    #region Ensure Security Role:

                    if (!(role.IsInRole(WindowsBuiltInRole.Administrator)))
                    {
                        // False:
                        _level = false;
                    }
                    else
                    {
                        // True:
                        _level = true;
                    }
                    #endregion
               }
          }
 } 

Something like that to ensure that it you can handle or at least alert the user that the feature may not work. Please note that in the above I actually protect the call and invoke the method; that way I can access the _level value at any point to ensure the authentication remains present. And it is only inherited or used when desired to avoid unnecessary calls. Hopefully that helps.


Update for Comment:

This is for your C# Project, you'd call the following:

using System.Diagnostics;

The above assembly will provide you the capability. Then inside a method just invoke the following.

Process command = new Process();
command.StartInfo.FileName = "notepad.exe";
command.Start();

As you can see it isn't to technical, but it will allow you to call a batch, open a program, or even run other utilities such as msiexec. Hopefully that helps.

Greg
  • 11,302
  • 2
  • 48
  • 79
  • can you explain me how to do step3 – user1731468 Feb 06 '13 at 10:48
  • and where must i place the "class Elevated_Rights" code? in the form1.cs? – user1731468 Feb 06 '13 at 12:15
  • @user1731468 The `Elevated_Rights` code can be used wherever, as all it will do is test the `UAC` as if that isn't set accordingly it won't allow your application to go on top of the `Start`. This test to and will attempt to query the proper user permission is present. – Greg Feb 06 '13 at 16:12
  • @user1731468 Step three is to create a `C++ .dll` that you may reference. In your C# application, that reference will allow you to inherit. – Greg Feb 06 '13 at 16:16
  • OK. An other question, is there a way i example can bring an other program to front (that's in the program files folder), example 'internet explorer'? – user1731468 Feb 06 '13 at 16:19
  • Is that just for your use, or for the application? For your use- If just for your use try this http://www.autohotkey.com/. That will allow you to script items, macros, or shortcut-keys in an automated fashion to automatically do a task. – Greg Feb 06 '13 at 16:34
  • for in the application, i want example when i 'recording a video'. To show 'notepad' also in the top of the Windows 8 start screen. I can type there live my comment for the viewer. Else it i must go back to the 'desktop' mode. – user1731468 Feb 06 '13 at 16:42
  • I don't quite understand what you mean? Are you looking for a way to restore all your Windows? – Greg Feb 06 '13 at 17:34
  • I will explain this again in other words. With the above code i can make my own app on the top (of the Windows Start menu). But can i call a other program (that is in the 'Program Files' folder) also to the top of the start menu -> example 'notepad.exe' – user1731468 Feb 06 '13 at 17:49
  • Yes you can, you can do that in several ways. One way would be to use `ProcessInfo` and actually invoke the `command` as if it were from the `command` Window to start the application. It's not good format in comment, I can give an example in my answer if you'd like. – Greg Feb 06 '13 at 17:59
  • I've provided an example, you may need to refine or tweak per your specification but it gives you an idea. – Greg Feb 06 '13 at 18:16
  • it open the program that's good, but it come not in top of the Windows start menu. – user1731468 Feb 06 '13 at 18:53
  • That will require some additional commands, which handle the window properties. – Greg Feb 06 '13 at 19:07
  • Sure but it will take some time some stuff just happened at office. – Greg Feb 06 '13 at 19:58
  • Sorry not yet I get hit by a giant blizzard. – Greg Feb 10 '13 at 15:48
  • I apologize for the delay, unfortunately a lot of life has just hit me all at once. Have you had any luck on your own? – Greg Feb 11 '13 at 17:43
  • no still nothing, it open that notepad, but it doesn't go to the foreground of the Windows8 start menu. Only my custom C# app. – user1731468 Feb 11 '13 at 19:57
  • Okay, I haven't had a real chance to deploy or do any real work. But, as soon as I have time I'll try and get something to help you out. It may be a week or two; a lot has happened. So I do apologize. – Greg Feb 11 '13 at 21:25