patch.exe ユーザーアカウント制御(UAC)対応版

patch.exeとはソースコードに差分を適用するUNIX由来のコマンドです。このpatch.exeはWindowsにも移植されているのですが、ユーザーアカウント制御(UAC)が有効になっている環境でpatch.exeを実行すると権限昇格ダイアログが表示されてしまうことがあります。

img

patch.exeのアイコンに表示されている盾マークは、ユーザーアカウント制御(UAC)の対象プログラムであることを示しています。

patch.exeを実行すると、以下のダイアログが表示されてしまいます。

次の不明な発行元からのプログラムにこのコンピューターへの変更を許可しますか?

img

ダウンロード

説明はいいから、ユーザーアカウント制御(UAC)の権限昇格ダイアログが表示されないpatch.exeが欲しいという方は以下のリンクからpatch.exeをダウンロードしてお使いください。

権限昇格のダイアログが表示される原因

ユーザーアカウント制御(UAC)については、UACのアーキテクチャに詳しく書かれています。

そのUACの機能の1つにインストーラー検出テクノロジーというものがあります。これはインストーラーと推測されるプログラムに対して自動的にUACを適用する機能です。patch.exepatchというインストーラーっぽいキーワードを含んでいるためにインストーラー検出テクノロジーによるUACが発動してしまうのです。

インストーラー検出テクノロジーによる検出対象は次の項目に限られています。(次の3つの条件をすべて満たす場合に対象となります。)

  • 32ビットの実行ファイル

  • 要求レベルの属性を持たないアプリケーション

  • UACを有効にして標準ユーザーとして実行される会話型プロセス

32ビットプロセスを作成する前に、次の属性を調べて、インストーラーであるかどうかを判断します。(次のいずれかの条件を満たす場合に対象となります。)

  • ファイル名に、“install”、“setup”、“update” などのキーワードが含まれている。

  • “バージョン リソース” フィールドに、“ベンダー”、“会社名”、“製品名”、“ファイルの説明”、“元のファイル名”、“内部名”、および “エクスポート操作の名前” のいずれかのキーワードが含まれている。

  • サイド バイ サイド マニフェスト内のキーワードが実行可能ファイルに埋め込まれている。

  • 特定の StringTable エントリ内のキーワードが実行可能ファイルにリンクされている。

  • リソース スクリプト データの主要な属性が実行可能ファイルにリンクされている。

  • 実行可能ファイル内に、対象となるバイトのシーケンスが存在する。

patch.exeをリネームして別の名前にすればUACの誤発動を回避することはできるのですが、そんなことはしたくないですよね。

今回は、要求レベルの属性を持たないアプリケーションという条件を崩すことでUACの誤発動を回避しようと思います。つまり、patch.exe要求レベルの属性を持つアプリケーションにすれば、UACは発動しなくなるわけです。

マニフェストを記述する

マニフェストは、XMLドキュメントです。これは、外部XMLファイルにすることも、アプリケーションにリソースとして埋め込むこともできます。マニフェストを記述することで、アプリケーションに様々な属性や振る舞いを指定するこができます。

前述の要求レベルの属性とはrequestedExecuteionLevelのことです。これを指定するマニフェストは以下のようになります。

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

このXMLをpatch.exe.manifestという名前で保存し、patch.exeと同じフォルダに配置します。これで、ユーザーアカウント制御(UAC)による権限昇格ダイアログは表示されなくなります。

マニフェストを実行ファイルに埋め込む

マニフェストを実行ファイルに埋め込むこともできます。patch.exe.manifestpatch.exeに埋め込んでファイルを1つにまとめてしまったほうが扱いやすいですよね。

mt.exeというツールを使用すると、マニフェストを実行ファイルに埋め込むことができます。mt.exeは、Visual StudioやWindows SDKに含まれています。

mt.exeを使用してマニフェストを埋め込む方法は、「マニフェストを C/C++ アプリケーションに埋め込む」で解説されています。

具体的には以下のコマンドで埋め込みができます。

mt.exe -manifest patch.exe.manifest -outputresource:patch.exe;1

mt.exeが見つかりませんか? 普通にコマンドプロンプトを起動しただけでは、PATHが設定されていないためにmt.exeを実行することができないかもしれません。そんなときは、スタートメニューからVisual Studioの「開発者コマンドプロンプト」を探して起動してみてください。開発ツールにPATHが通った状態のコマンドプロンプトが開きます。

マニフェストを埋め込んで、インストーラー検出テクノロジーに誤判定されないようにしたpatch.exeはアイコンに盾マークが表示されなくなります。

img

自分でマニフェストを埋め込むのが面倒という方は、マニフェストを埋め込んでUAC対応にしたpatch.exeダウンロードしてお使いください。

マニフェスト埋め込み前のオリジナルのpatch.exeは以下のサイトからダウンロードすることができます。

patchコマンドの実行時にエラーが出てしまうときは?

patchコマンドでパッチを適用しようとしたときに、以下のエラーが出ることがあるかもしれません。

Assertion fafiled: hunk, file ../patch-2.5.9-src/patch.c, line 354

This application has requested the Runtime to terminate it in an unusual way. Please contact the application’s support team for more information.

これはパッチファイルの改行コードがLFだけの場合に発生することがあります。パッチファイルの改行コードをCR+LFに変更して、正しく動作するか試してみてください。