Skip to content

Commit

Permalink
Embed the manifest on Windows, so no elevation is performed
Browse files Browse the repository at this point in the history
This would be much cleaner if the build scripts were actually fucking
documented properly

Gigantic thanks to @TheCatPlusPlus who saved the day once again
(solution heavily based on
https://github.com/TheCatPlusPlus/rust-manifest-test)

Ref: #11
Closes #13
  • Loading branch information
nabijaczleweli committed Nov 16, 2016
1 parent 143502e commit ef4346c
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 38 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
!LICENSE
!Cargo.toml
!rustfmt.toml
!build.rs
!cargo-install-update-manifest.rc
!cargo-install-update.exe.manifest
!*.sublime-project
!*.md
!src
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ repository = "https://github.com/nabijaczleweli/cargo-update"
readme = "README.md"
keywords = ["cargo", "update", "plugin", "subcommand"]
license = "MIT"
build = "build.rs"
# Remember to also update in appveyor.yml
version = "0.5.0"
# Remember to also update in cargo-install-update.md
Expand Down
37 changes: 0 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,40 +26,3 @@ On Windows the following strategy is applied:
* Check for old versions, remove them
* Add the current version to the current executable's extension
* Create an empty file in place of the just-renamed file (this way `cargo install` will "replace" it and not duplicate the entry in `.crates.toml`)

### Auto-elevation (and failures thereof) on Windows

For legacy compatibility reasons Windows will try to elevate `cargo-install-update.exe` which will result in something akin to:

```
C:\Users\liigo>cargo install-update
error: An unknown error occurred
To learn more, run the command again with --verbose.
C:\Users\liigo>cargo install-update --verbose
error: An unknown error occurred
To learn more, run the command again with --verbose.
```

That's a known issue, but it's *unresolvable* out of the box until [RFC721](https://github.com/rust-lang/rfcs/issues/721) is accepted.

However, one can override the heuristics by creating a file named `cargo-install-update.exe.manifest` next to the binary itself with the content:

```xml
<?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>
```

That way Windows will no longer try to elevate the executable, which will result in it working flawlessly,

See [#11](https://github.com/nabijaczleweli/cargo-update/issues/11) for discussion.
23 changes: 23 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use std::process::Command;
use std::path::Path;
use std::env;

fn main() {
if cfg!(target_os = "windows") {
let out_dir = env::var("OUT_DIR").unwrap();

Command::new("windres")
.args(&["--input", "cargo-install-update-manifest.rc", "--output-format=coff", "--output"])
.arg(&format!("{}/cargo-install-update-manifest.res", out_dir))
.status()
.unwrap();

Command::new("ar")
.args(&["crs", "libcargo-install-update-manifest.a", "cargo-install-update-manifest.res"])
.current_dir(&Path::new(&out_dir))
.status()
.unwrap();

println!("cargo:rustc-link-search=native={}", out_dir);
}
}
2 changes: 2 additions & 0 deletions cargo-install-update-manifest.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#include "winuser.h"
1 RT_MANIFEST cargo-install-update.exe.manifest
10 changes: 10 additions & 0 deletions cargo-install-update.exe.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?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>
2 changes: 1 addition & 1 deletion cargo-update.sublime-project
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"follow_symlinks": true,
"name": "Build scripts",
"path": ".",
"file_include_patterns": ["Cargo.*", "*.yml"],
"file_include_patterns": ["Cargo.*", "*.yml", "build.rs"],
"folder_exclude_patterns": ["*"]
},
]
Expand Down
7 changes: 7 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
// This is so cargo actually considers linking to the fucking manifest,
// since the build scripts' documentation can do the digital equivalent of fucking off
#[cfg(target_os="windows")]
#[link(name="cargo-install-update-manifest", kind="static")]
extern "C" {}


extern crate cargo_update;
extern crate tabwriter;
extern crate regex;
Expand Down

0 comments on commit ef4346c

Please sign in to comment.