Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows: rustc should embed application manifest into executables #10512

Closed
vadimcn opened this issue Nov 16, 2013 · 6 comments · Fixed by #10878
Closed

Windows: rustc should embed application manifest into executables #10512

vadimcn opened this issue Nov 16, 2013 · 6 comments · Fixed by #10878
Labels
A-linkage Area: linking into static, shared libraries and binaries O-windows Operating system: Windows

Comments

@vadimcn
Copy link
Contributor

vadimcn commented Nov 16, 2013

Windows executables should contain embedded application manifests [1].

This is especially important for 32-bit executables, because in the absence of a manifest they are subject to UAC installer detection heuristics [2], which may cause unexpected UAC prompts or even complete failure to execute (in unattended contexts) depending on presence of certain keywords in executable's file name.

  1. http://msdn.microsoft.com/en-us/library/aa374191.aspx
  2. http://technet.microsoft.com/en-us/library/cc709628.aspx
@poiru
Copy link
Contributor

poiru commented Nov 16, 2013

You beat me by a few hours :) Here is the description I had in #10515:

The UAC issue in #10452 is caused by a missing manifest in the binaries. We should include the following in all binaries:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
        <security>
            <requestedPrivileges>
                <requestedExecutionLevel level="asInvoker" uiAccess="false" />
            </requestedPrivileges>
        </security>
    </trustInfo>
</assembly>

In an ideal world, we would allow the user to provide a custom manifest should they wish to require UAC elevation, for example. As another example, a user might want to provide supportedOS entries in order to fully support Windows 8.1 (where the GetVersion()/GetVersionEx() functions lie about the Windows version unless <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" /> is present in the manifest).

The VC++ linker has the /MANIFESTUAC option for the UAC part.

In a traditional MinGW build, this would be implemented something like this:

windres -i resource.rc -o resource.o
gcc -c main.c -o main.o
gcc -o app.exe main.o resource.o -s -Wl,--subsystem,windows

Where resource.rc would contain something like this (application.manifest would contain the XML stuff above):

#include <Windows.h>

// ...

CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "application.manifest"

@vadimcn
Copy link
Contributor Author

vadimcn commented Nov 16, 2013

I wonder if it would be easier to skip windres altogether and write resource directly into linked executable using Resource API.

@klutzy
Copy link
Contributor

klutzy commented Nov 16, 2013

@poiru I use rustc.exe main.rs --link-args resource.o to add manifest but I always felt this is a hack.

@glandium
Copy link
Contributor

As of MSVC 2008, passing /MANIFEST:EMBED to link.exe should add the necessary manifest bits for UAC.

@poiru
Copy link
Contributor

poiru commented Jul 31, 2020

In case anyone finds this issue, you can use winres in a build.rs script to solve this:

#[cfg(target_os = "windows")]
extern crate winres;

fn main() {
    #[cfg(target_os = "windows")]
    {
        let mut res = winres::WindowsResource::new();
        res.set_manifest(
            r#"
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
  <security>
    <requestedPrivileges>
      <requestedExecutionLevel level="asInvoker" uiAccess="false" />
    </requestedPrivileges>
  </security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
  <application>
    <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/><!-- 7 -->
    <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/><!-- 8 -->
    <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/><!-- 8.1 -->
    <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/><!-- 10 -->
  </application>
</compatibility>
</assembly>
"#,
        );
        res.compile().unwrap();
    }
}

@MeerMusik
Copy link

In case anyone finds this issue, you can use winres in a build.rs script to solve this:
Hello.

It is over 1 year later now since this comment was posted. Is this nasty work around still necessary? Or does the Rust Compiler finally supports embedding Windows Manifest Files and Resources etc. (in anyway whatsoever)?

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries O-windows Operating system: Windows
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants