2

WIX を使用して (MSHC から生成された) CAB ヘルプ ファイルをインストールするのに苦労しています。私が従おうとした基本的なレシピは、次のとおりです: Installing Help with Help Library Manager and WiX

私の特定のケースでは、レシピではなく、x64/x86 ターゲットで苦労しています。各ターゲットに 1 つずつ、2 つのインストーラーを作成する方法を説明するWiX のトリックとヒントからの WIX のヒントを読みました。ただし、インストーラーは 2 つではなく 1 つだけにしたいので、x86 ターゲットのみを実装することにしました。

x64 プラットフォームを使用してインストールすると、すべて正常に動作します。x86 で同じことをしようとすると、見つからないというエラーが表示されますHelpLibManager.exe。よく調べてみると、これは 64 ビットC:\Program Files\Microsoft Help Viewer\v1.0\HelpLibManager.exeにインストールされているのに対し、WIX は x86 フォルダーを使用しているため、妥当なようC:\Program Files (x86)\Microsoft Help Viewer\v1.0\HelpLibManager.exeです。

これを修正するために、HelpLibManager がインストールされている場所を含むレジストリから正しいパスを読み取ろうとしました。

<Property Id="HELPLIB">
  <RegistrySearch Id="HelpLib"
                  Root="HKLM"
                  Key="Software\Microsoft\Help\v1.0"
                  Name="AppRoot"
                  Type="raw" />
</Property>

<SetProperty Id="HELPLIBMANAGER"
         Value="[HELPLIB]HelpLibManager.exe"
         After="InstallInitialize"
         Sequence="execute"/>

レジストリを調べると (Wow6432Nodeもちろん)、このキーの値は次のように表示されます: c:\Program Files\Microsoft Help Viewer\v1.0\- これは正しいです。ただし、MSI のログを見ると、次のように表示されていますが"C:\Program Files (x86)\Microsoft Help Viewer\v1.0\HelpLibManager.exe"、これは正しくありません。

Property(S): HELPLIB = C:\Program Files (x86)\Microsoft Help Viewer\v1.0\

どうやら Wix は、レジストリから読み取った文字列値を変更するようです。

これを修正する適切な方法を誰かに説明してもらえますか?

4

2 に答える 2

2

(x86) フォルダーへのリダイレクトは、WiX ではなく、Windows インストーラーによって自動的に行われます。他のセットアップ オーサリング ツールを使用してパッケージを作成している場合も、同じことが起こります。

残念ながら、32 ビット インストーラーは、x64 マシンの "Program Files" フォルダーに書き込むことができません。OS からの WOW リダイレクトは、インストール中にこれを制御します。

HKLM\Software\Wow6432Node の下ではなく、HKLM\Software の下に直接レジストリ エントリを作成するには、そのコンポーネントを 64 ビットとしてマークするだけです。残念ながら、これはファイルに対しては同じようには機能しません。つまり、ファイルのコンポーネントが 64 ビットとしてマークされていても、OS は Program Files (x86) の下のすべてのファイルとフォルダーをリダイレクトします。

編集:

私が最も驚いたのは、レジストリから読み取られた文字列値が変更されていることです (ダンプされたプロパティ値を参照してください)。

これが私にとって初めて起こったとき、私も驚いた.

そのフォルダーからファイルを起動するには、小さなトリックを使用して、DLL を output として小さなカスタム アクション C#を作成すれば、まだ可能性があります。カスタムアクションで検索の値を取得して解析し、存在する場合は手動で「(x86)」部分を削除できます。次に、 WOW リダイレクトを一時的に無効にし、ファイルを起動してから、WOW リダイレクトを再度有効にします。

カスタム アクションに条件を設定し、VersionNT64 プロパティのみが設定され、インストール時にのみ実行されることを忘れないでください。

于 2013-02-21T10:09:08.690 に答える
0

Bogdan Mitrache の回答を例で完成させたいと思います。これを実行するには、C# カスタム アクションを使用してレジストリにアクセスし、WOW の動作を制御します。

public partial class CustomActions
    {

        #region marshalling RegCreateKeyEx RegOpenKeyEx RegCloseKey RegSetValueEx
        [Flags]
        public enum RegOption
        {
            NonVolatile = 0x0,
            Volatile = 0x1,
            CreateLink = 0x2,
            BackupRestore = 0x4,
            OpenLink = 0x8
        }

        [Flags]
        public enum RegSAM
        {
            QueryValue = 0x0001,
            SetValue = 0x0002,
            CreateSubKey = 0x0004,
            EnumerateSubKeys = 0x0008,
            Notify = 0x0010,
            CreateLink = 0x0020,
            WOW64_32Key = 0x0200,
            WOW64_64Key = 0x0100,
            WOW64_Res = 0x0300,
            Read = 0x00020019,
            Write = 0x00020006,
            Execute = 0x00020019,
            AllAccess = 0x000f003f
        }

        public enum RegResult
        {
            CreatedNewKey = 0x00000001,
            OpenedExistingKey = 0x00000002
        }

        //[StructLayout(LayoutKind.Sequential)]
        //public class SECURITY_ATTRIBUTES
        //{
        //    public int nLength;
        //    public unsafe byte* lpSecurityDescriptor;
        //    public int bInheritHandle;
        //}
        [StructLayout(LayoutKind.Sequential)]
        public class SECURITY_ATTRIBUTES
        {
            public int nLength;
            public IntPtr lpSecurityDescriptor;
            public int bInheritHandle;
        }

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern int RegCreateKeyEx(
                    RegistryHive hKey,
                    string lpSubKey,
                    int Reserved,
                    string lpClass,
                    RegOption dwOptions,
                    RegSAM samDesired,
                    SECURITY_ATTRIBUTES lpSecurityAttributes,
                    out UIntPtr phkResult,
                    out RegResult lpdwDisposition);

        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegOpenKeyEx")]
        static extern int RegOpenKeyEx(
            RegistryHive hKey,
            string subKey,
            uint options,
            RegSAM sam,
            out UIntPtr phkResult);

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern int RegCloseKey(
            UIntPtr hKey);

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern uint RegSetValueEx(
             UIntPtr hKey,
             [MarshalAs(UnmanagedType.LPStr)]
     string lpValueName,
             int Reserved,
             RegistryValueKind dwType,
             [MarshalAs(UnmanagedType.LPStr)] string lpData,
             int cbData);

        const int KEY_WOW64_64KEY = 0x0100;
        const int KEY_READ = 0x20019;

        #endregion

   private static uint WriteValue_String(UIntPtr hKey, string sName, string sValue)
        {
            uint setRes = RegSetValueEx(hKey, sName, 0, Microsoft.Win32.RegistryValueKind.String, sValue, sValue.Length + 1);
            return setRes;
        }

        /// <summary>
        /// Enable AutoLogon by changing the values of the system registry keys "DefaultUserName", "DefaultPassword" and "AutoAdminLogon" 
        /// in "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
        /// </summary>
        /// <param name="session"></param>
        /// <returns></returns>
        [CustomAction]
        public static ActionResult EnableAutoLogon(Session session)
        {
            _session = session;
            LogUtil.WriteDebugInfo(session, "Enter Function");
            try
            {

                SECURITY_ATTRIBUTES secAttribs = new SECURITY_ATTRIBUTES();

                UIntPtr hKey;
                RegResult regResult;

                LogUtil.WriteDebugInfo(session, "RegOpenKeyEx");
                int result = RegOpenKeyEx(
                    RegistryHive.LocalMachine,
                    @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon",
                    0, //must be 0
                    RegSAM.WOW64_64Key | RegSAM.SetValue,
                    out hKey);

                LogUtil.WriteDebugInfo(session, "WriteValue_String");
                uint setRes = WriteValue_String(hKey, "DefaultUserName", "admin");
                setRes = WriteValue_String(hKey, "DefaultPassword", "admin");
                setRes = WriteValue_String(hKey, "AutoAdminLogon", "1");

                LogUtil.WriteDebugInfo(session, "RegCloseKey");
                int closeRes = RegCloseKey(hKey);           
            }
            catch (System.Exception ex)
            {
                LogUtil.WriteDebugInfo(session, "Exception occured : " + ex.Message + "\n" + ex.StackTrace);
                LogUtil.WriteDebugInfo(session, "Exit Function");
                return ActionResult.Failure;
            }
            LogUtil.WriteDebugInfo(session, "Exit Function");
            return ActionResult.Success;
        }
 }

KEY_WOW64_32KEY (0x0200) 64 ビット Windows 上のアプリケーションが 32 ビット レジストリ ビューで動作する必要があることを示します。このフラグは、32 ビット Windows では無視されます。詳細については、代替レジストリ ビューへのアクセスを参照してください。

このフラグは、OR 演算子を使用して、レジストリ値を照会またはアクセスするこの表の他のフラグと組み合わせる必要があります。

Windows 2000: このフラグはサポートされていません。

KEY_WOW64_64KEY (0x0100) 64 ビット Windows 上のアプリケーションが 64 ビット レジストリ ビューで動作する必要があることを示します。このフラグは、32 ビット Windows では無視されます。詳細については、代替レジストリ ビューへのアクセスを参照してください。

このフラグは、OR 演算子を使用して、レジストリ値を照会またはアクセスするこの表の他のフラグと組み合わせる必要があります。

Windows 2000: このフラグはサポートされていません。

于 2013-06-24T07:40:41.757 に答える