11

I have an application that writes program settings to the windows registry that is absolutely necessary so.storing to a file is not an option.

To simplify this, I would like to give an "admin privileges" nag screen instead of trying to explain how to right click on the program file/short cut.

I found a reasonably good article but I receive a duplicate resource error after adding my own resource file for the manifest.

This is supposedly due to a conflict with the internal manifest and to resolve the issue I see a lot of comments suggesting "enable runtime themes" to be disabled in project options. I have gone through every menu but cannot find it and I've now been told that it may not be available in Delphi 7 and was introduced in later versions.

How can I add my own manifest?

TLama
  • 75,147
  • 17
  • 214
  • 392
Clinton
  • 347
  • 1
  • 2
  • 14
  • 4
    Writing program settings to the registry is not a proper cause to give your application admin privileges! this is a very bad idea. – kobik Feb 05 '13 at 10:29
  • 1
    One does wonder why you don't do what every other developer does and write the program settings to the correct location. – David Heffernan Feb 05 '13 at 12:42
  • I'm writing them to Hkey current user which from what I read, it should be writable without admin. – Clinton Feb 05 '13 at 12:50
  • 2
    Writing to HKCU does not require admin rights. so why do need to be one? You still *need* to include a UAC manifest but with `level="asInvoker"` which probably does not change your problem with the dup resource. – kobik Feb 05 '13 at 12:54
  • Correct. This, as you can probably tell, is my first manifest attempt. The reason I'm going for admin is because I know it works. Once I have something working, I can then focus on the manifest and the different levels and get it fine tuned. – Clinton Feb 05 '13 at 13:09

3 Answers3

27

I already commented that "Writing program settings to the registry is not a proper cause to give your application admin privileges". However it is a good idea to include a UAC manifest in any case. the common requestedExecutionLevel should be level="asInvoker". see the docs

"Q: Adding manifest for admin rights request for delphi 7"

Create the below 4 files (2 sets):


(UAC Only)

uac.manifest

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="MyApp" type="win32"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>

uac.rc

1 24 "uac.manifest"

(UAC + XP Themes)

uac_xp.manifest

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32" name="MyApp" version="1.0.0.0" processorArchitecture="x86"/>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="Microsoft.Windows.Common-Controls"
        version="6.0.0.0"
        publicKeyToken="6595b64144ccf1df"
        language="*"
        processorArchitecture="*"/>
    </dependentAssembly>
  </dependency>
  <!-- Windows Vista application security requirements. -->
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="requireAdministrator"
          uiAccess="false"/>
        </requestedPrivileges>
       </security>
  </trustInfo>
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <!--Windows 7-->
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
      <!--Windows Vista-->
      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
    </application>
  </compatibility>   
</assembly>

uac_xp.rc

1 24 "uac_xp.manifest"

Add the desired rc file (uac.rc or uac_xp.rc) to your project via the "Project > Add to project" menu item. This will create the {$R} directive in your project file:

program Project1;

{.$R 'uac.res' 'uac.rc'} // UAC only
// OR
{$R 'uac_xp.res' 'uac_xp.rc'} // UAC + XP Themes

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.RES}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

Note the {$R 'uac_xp.res' 'uac_xp.rc'}. Delphi will auto compile the rc to res file.

Alternatively you can compile the rc file via brcc32 uac.rc outside Delphi IDE. and then add {$R 'uac_xp.res'} manually to your project.


Make sure you don't use any other XP manifest.

kobik
  • 21,001
  • 4
  • 61
  • 121
  • 1
    It seems your method of adding the resource seems to solve the issue compared to adding the res in the project using the ide. I hear what you are saying about admin but I'm now able to play with the settings to see what is allowed and not. – Clinton Feb 06 '13 at 13:44
  • 2
    @Redshift, Regarding your edit: note the `{$R 'uac_xp.res' 'uac_xp.rc'}`. Delphi will auto compile the `rc` to `res` file, so no need to compile the `rc` file via `brcc32 uac.rc`. If you use `{$R 'uac_xp.res'}` only then you need to compile the `rc` file outside Delphi IDE. – kobik Nov 01 '13 at 22:33
  • FYI, in modern Delphi versions, you can specify the path to a custom .manifest file directly in the Project Options instead of using an .rc/.res file. – Remy Lebeau Oct 03 '14 at 17:23
  • See http://docwiki.embarcadero.com/RADStudio/XE7/en/Application_Options.Set "Enable runtime themes" to "Custom manifest". – Remy Lebeau Oct 03 '14 at 17:29
  • Slight correction to the Embarcadero docwiki URL -- this is where you can (today) see info on Delphi XE7 Application Options: http://docwiki.embarcadero.com/RADStudio/XE7/en/Application_Options – user424855 Feb 25 '15 at 23:39
  • This is a great answer, and clearly explains the steps (unlike many other articles) but the final step didn't work for me in Delphi 7. Delphi did not auto-compile the rc to res file. Instead the IDE compiler gave me: WARNING: File not found: 'uac.res', and ERROR File not found: 'uac.res'. I had to do the brcc32 uac.rc step. Note that the Delphi 7 Help for $R says nothing about auto-compiling at all, but rather including both file names will "make the .rc file appear in the Project Manager" (it didn't). But thank you for including the brcc32 line, because that got me to the solution. – FreeText Nov 10 '15 at 21:24
  • It might be worth noting that using a period (".") before the compiler directive comments out the directive. E.g. "{.$R uac.res}" (without quotes) does not use the uac. res file. For those who don't use compiler directives often... – FreeText Nov 10 '15 at 22:34
  • @FreeText, have you used the syntax `{$R 'uac_xp.res' 'uac_xp.rc'}` to auto compile? – kobik Nov 11 '15 at 05:44
  • I was just using the uac.res and uac.rc files (w/o xp). I tried it, it didn't work for me in D7, Win7. See warning and error above. The only time it didn't complain with that line is if the res file already existed; once I delete it, I get the error again. I saw no sign of it being compiled as part of the project. I checked the syntax over and over, added and removed the optional single quotes, etc. I tried adding the uac.rc file to the project. I tried Build as well as Compile. All to no effect. Does it work for you? – FreeText Nov 11 '15 at 16:47
  • Worked with no problems in D5. on D7 I had to add the rc file to the project. I made an edit to my answer. look also: http://stackoverflow.com/questions/1298031/including-resource-file-in-a-project-by-rc-file-rather-than-res-file – kobik Nov 11 '15 at 17:27
  • Interesting. I had the line in, then I tried adding it, and it didn't work. This time w/o the $R line, I added the .rc file to the project, then Delphi added the line and the Delphi project compiles the file with the other files as per usual. I.e. it works. Strange. There must be another entry somewhere. In any case, it does work for me in this way (but only in this order of steps). Thanks! – FreeText Nov 11 '15 at 19:18
13

How to remove the "internal" manifest from Delphi 7 project ?

That internal manifest was in Delphi 7 times represented by the TXPManifest component, whose only purpose was to add the XPMan.pas unit to the uses clause of a form's unit where it was dropped. This XPMan.pas unit then included the resource file with the manifest itself into a project output.

So, to remove this internal manifest, you need to remove all TXPManifest components from all of the forms of your project (if you used them), as well as all the XPMan uses clause references from all units of your project.

In short, do the following two steps for all units of your project (the first step is optional if you didn't used the TXPManifest components, but the second):

enter image description here

TLama
  • 75,147
  • 17
  • 214
  • 392
  • No Xpmanifest compoent or Xpman declarations on any of the forms. – Clinton Feb 05 '13 at 12:20
  • That's just one (common way in Delphi 7, I'd say) of the ways how to add a manifest to the application. So, if that didn't help, try to search for all included resources `{$R ResourceFileName.res}` as before, in the whole project. There can be one, which includes the manifest (the name of the resource file can be any). – TLama Feb 05 '13 at 12:37
6

In newer versions of Delphi this is no longer necessary.
Under Project Options, then Application, there is a section for the manifest:

Manifest options
Screenshot from version 10.2.1 Tokyo

enter image description here Screenshot from version 11.1.3 Alexandria

This automatically takes care of the XP manifest mentioned as a warning at the bottom of Kobik's answer.

I do not know from which Delphi version this was available.
(Free free to edit this answer if you know). (Edit Ian Murphy Feb 2019: It is not available in XE2)

Jan Doggen
  • 8,799
  • 13
  • 70
  • 144