forked from libxmlplusplus/libxmlplusplus
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tools/build_scripts: Add script to generate UAC manifests
We need to add this script to generate Windows manifest files during the build to allow test programs with 'update' in the filename to run without UAC from getting into our way, for 32-bit Windows builds. The following commits will update the build files to embed this manifest as appropriate, so that test programs can run properly on 32-bit Windows builds.
- Loading branch information
Showing
2 changed files
with
138 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
#!/usr/bin/env python3 | ||
# | ||
# Copyright © 2021 Chun-wei Fan. | ||
# | ||
# SPDX-License-Identifier: LGPL-2.1-or-later | ||
# | ||
# Original author: Chun-wei Fan <[email protected]> | ||
|
||
""" | ||
This script generates a Windows manifest file and optionally a resource file to | ||
determine whether a specified program requires UAC elevation | ||
""" | ||
|
||
import os | ||
import argparse | ||
|
||
DOMAIN_NAME = "gnome" | ||
|
||
|
||
def main(): | ||
parser = argparse.ArgumentParser(description=__doc__) | ||
parser.add_argument( | ||
"-p", "--package", required=True, help="package name of the executable" | ||
) | ||
parser.add_argument("-n", "--name", required=True, help="name of executable") | ||
parser.add_argument( | ||
"--pkg-version", required=True, dest="version", help="version of package" | ||
) | ||
parser.add_argument( | ||
"--require-admin", | ||
action="store_true", | ||
dest="admin", | ||
default=False, | ||
help="require admin access to application", | ||
) | ||
parser.add_argument( | ||
"--input-resource-file", | ||
dest="resource", | ||
default=None, | ||
help="existing .rc file to embed UAC manifest (do not generate a new .rc file), must have included windows.h in it", | ||
) | ||
parser.add_argument( | ||
"--output-dir", | ||
dest="outdir", | ||
default=None, | ||
help="directory to output resulting files", | ||
) | ||
args = parser.parse_args() | ||
|
||
if args.resource is not None: | ||
if not os.path.isfile(args.resource): | ||
raise FileNotFoundError( | ||
"Specified resource file '%s' does not exist" % args.resource | ||
) | ||
|
||
generate_manifest(args.package, args.name, args.version, args.admin, args.outdir) | ||
write_rc_file(args.name, args.resource, args.outdir) | ||
|
||
|
||
def generate_manifest(package, name, version, admin, outdir): | ||
if version.count(".") == 0: | ||
manifest_package_version = version + ".0.0.0" | ||
elif version.count(".") == 1: | ||
manifest_package_version = version + ".0.0" | ||
elif version.count(".") == 2: | ||
manifest_package_version = version + ".0" | ||
elif version.count(".") == 3: | ||
manifest_package_version = version | ||
else: | ||
parts = version.split(".") | ||
manifest_package_version = "" | ||
for x in (0, 1, 2, 3): | ||
if x == 0: | ||
manifest_package_version += parts[x] | ||
else: | ||
manifest_package_version += "." + parts[x] | ||
|
||
if outdir is not None: | ||
output_file_base_name = os.path.join(outdir, name) | ||
else: | ||
output_file_base_name = name | ||
|
||
outfile = open(output_file_base_name + ".exe.manifest", "w+") | ||
outfile.write("<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n") | ||
outfile.write( | ||
"<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>\n" | ||
) | ||
outfile.write(" <assemblyIdentity version='%s'\n" % manifest_package_version) | ||
outfile.write(" processorArchitecture='*'\n") | ||
outfile.write(" name='%s.%s.%s.exe'\n" % (DOMAIN_NAME, package, name)) | ||
outfile.write(" type='win32' />\n") | ||
outfile.write(" <trustInfo xmlns='urn:schemas-microsoft-com:asm.v3'>\n") | ||
outfile.write(" <security>\n") | ||
outfile.write(" <requestedPrivileges>\n") | ||
outfile.write(" <requestedExecutionLevel\n") | ||
|
||
if admin: | ||
outfile.write(" level='requireAdministrator'\n") | ||
else: | ||
outfile.write(" level='asInvoker'\n") | ||
|
||
outfile.write(" uiAccess='false' />\n") | ||
outfile.write(" </requestedPrivileges>\n") | ||
outfile.write(" </security>\n") | ||
outfile.write(" </trustInfo>\n") | ||
outfile.write("</assembly>\n") | ||
outfile.close() | ||
|
||
|
||
def write_rc_file(name, resource, outdir): | ||
if outdir is not None: | ||
output_file_base_name = os.path.join(outdir, name) | ||
else: | ||
output_file_base_name = name | ||
|
||
if resource is None: | ||
outfile = open(output_file_base_name + ".rc", "w+") | ||
outfile.write("#define WIN32_LEAN_AND_MEAN\n") | ||
outfile.write("#include <windows.h>\n") | ||
else: | ||
if resource != output_file_base_name + ".rc": | ||
outfile = open(output_file_base_name + ".rc", "w+") | ||
else: | ||
outfile = open(output_file_base_name + ".final.rc", "w+") | ||
srcfile = open(resource, "r") | ||
outfile.write(srcfile.read()) | ||
srcfile.close() | ||
|
||
outfile.write("\n") | ||
outfile.write( | ||
'CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "%s.exe.manifest"' % name | ||
) | ||
outfile.close() | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |