2012-08-15 36 views
2

我有一個自定義動作項目,其中包含由我的公司創建的安裝程序使用的各種CA,其中一些用於通過Microsoft操作IIs7 .Web.Administration API。將新的自定義動作添加到項目中可防止運行現有的自定義動作

我添加了一個名爲SetApplicationAutoStart的新自定義操作,該操作是包含IIs相關CA的類。此自定義操作用於設置強制II預加載並啓動WCF服務的autoStart屬性,以便初始響應時間更短。

添加此操作後,名爲SetAppPoolLoadUserProfileTrue的現有CA停止工作。即使計算機上的默認站點已更改,以便該設置爲false,此CA也會將該站點上的設置強制爲true,因此我們確實需要它的工作。

當操作失敗時,日誌文件包含以下行。

MSI (s) (A0:18) [15:02:43:639]: Executing op: ActionStart(Name=SetAppPoolLoadUserProfileTrue,,) 
Action 15:02:43: SetAppPoolLoadUserProfileTrue. 
MSI (s) (A0:18) [15:02:43:641]: Executing op: CustomActionSchedule(Action=SetAppPoolLoadUserProfileTrue,ActionType=3073,Source=BinaryData,Target=SetAppPoolLoadUserProfileTrue,CustomActionData=AppPoolName=xxxxx) 
MSI (s) (A0:18) [15:02:43:670]: Creating MSIHANDLE (377) of type 790536 for thread 50712 
MSI (s) (A0:C8) [15:02:43:670]: Invoking remote custom action. DLL: C:\Windows\Installer\MSIBD82.tmp, Entrypoint: SetAppPoolLoadUserProfileTrue 
CustomAction SetAppPoolLoadUserProfileTrue returned actual error code 1154 (note this may not be 100% accurate if translation happened inside sandbox) 
MSI (s) (A0:C8) [15:02:43:673]: Closing MSIHANDLE (377) of type 790536 for thread 50712 
MSI (s) (A0:18) [15:02:43:674]: Note: 1: 1723 2: SetAppPoolLoadUserProfileTrue 3: SetAppPoolLoadUserProfileTrue 4: C:\Windows\Installer\MSIBD82.tmp 
Error 1723. There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run. Contact your support personnel or package vendor. Action SetAppPoolLoadUserProfileTrue, entry: SetAppPoolLoadUserProfileTrue, library: C:\Windows\Installer\MSIBD82.tmp 
MSI (s) (A0:18) [15:20:25:139]: Product: xxxxxxx -- Error 1723. There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run. Contact your support personnel or package vendor. Action SetAppPoolLoadUserProfileTrue, entry: SetAppPoolLoadUserProfileTrue, library: C:\Windows\Installer\MSIBD82.tmp 
Action ended 15:20:25: InstallFinalize. Return value 3. 

這看起來像是一個問題,從PE中爲此操作提取dotnet PE。二進制中的所有其他CA都可以正常工作,包括新的CA。

+0

請注意Visual Studio在構建我的解決方案(配置管理器)時未預先選擇要構建的CustomActions項目。這可能會導致意外的過時的自定義操作程序集。 – 2016-05-04 15:12:19

回答

2

同樣的事情發生在我身上。 「galets」已經指向了正確的方向,讓我走上了正軌(沒有代表upvote,抱歉)。

短版:

MakeSfxCA生產機DLL不按PE/COFF規範導致了觀察到的行爲。

龍版本:

  1. 構建一個CA,例如「HavocAction」具有三個導出入口點(即標記有「CustomAction」屬性),名爲「HavocEntryPointa」,「HavocEntryPointB」,「HavocZappEntryPoint」(介意確切的拼寫)。這些方法可能會返回「ActionResult.Success」。
  2. 拿出簡單的設置,一個)調用只是 「HavocEntryPointa」,B)只是調用 「HavocEntryPointB」
  3. ==>設置 「一)」 會工作,設置 「二)」 將失敗
  4. 取消對在 「HavocZappEntryPoint」 和行爲 「CustomAction」 屬性反轉,即
  5. ==>設置 「一)」 會失敗,設置 「二)」 將工作

進一步分析

當你轉儲包裝的CA.dll文件與

DUMPBIN /出口HavocAction.CA.dll

你喜歡的東西(節選)

125 7C 00003A36 
126 7D 00003A4C HavocEntryPointa 
127 7E 00003A62 HavocEntryPointB 
128 7F 00003A78 HavocZappEntryPoint 
129 80 000042FC zzzEmbeddedUIHandler 
130 81 000043B8 zzzInitializeEmbeddedUI 
131 82 0000467F zzzShutdownEmbeddedUI 
132 83 00003AA5 zzzzInvokeManagedCustomActionOutOfProcW 

這是錯誤的(搜索 「pecoff_v83.docx」,比照。 Exported DLL functions not ordered lexically?)。條目應該被排序(通過ASCII),以便在從dll加載方法(條目「HavocEntryPointa」和「HavocEntryPointB」互換)時執行二進制搜索。

我的教育猜測是,當從dll加載代碼時,二分查找失敗,導致錯誤。由於二進制搜索的性質,刪除「HavocZappEntryPoint」會顛倒效果。

關於備註OP

Kjartan第一次使用「SetApplicationAutoStart」和「SetAppPoolLoadUserProfileTrue」,這是不正常出口到CA.dll由於錯誤排序;大寫字母「P」在小寫字母「l」之前,但是這由MakeSfxCA互換。他的後一種選擇「ConfigureApplicationAutoStart」和「SetAppPoolLoadUserProfileTrue」按照PE/COFF規範排序。

PS:現在是http://wixtoolset.org/issues/4502

更新

PPS:與維克斯3.9 RC3版本包含此問題的bug修復啓動;一切都按預期工作。

+0

將此更改爲正確的答案,因爲這將允許人們創建適當的解決方法。 – 2014-08-22 16:31:22

+0

Wix 3.10在Win10上存在該錯誤:( – 2016-08-05 20:36:19

1

其實,這是很奇怪,但很長一段時間後,尋找問題的答案,並試圖不同的東西我試圖改變從SetApplicationAutoStart到ConfigureApplicationAutoStart新的CA的名字很多的,並且導致SetAppPoolLoadUserProfileTrue重新開始正常工作

+0

我也看到某個.DLL打破了CA的功能,只是重命名這個.DLL文件才能啓動並運行。很奇怪。 – 2014-08-04 15:41:02

2

我經歷過,確切地說與您所描述的症狀相同。 WiX工具集似乎存在問題。我的WiX tolset版本是3.8,我也有一個自定義操作,不會運行,並且更改它的名字可以解決問題。 SFX編譯器只是編譯了沒有任何問題跡象的損壞的DLL。更糟糕的是,在我的情況下,這是一個應該使用Result =「ignore」卸載時運行的函數,所以我甚至沒有任何即時的跡象表明在運行實際安裝程序後出現問題。

我試着試着弄明白到底是什麼問題,並沒有找到任何令人滿意的解釋。在源代碼中,違規函數的位置似乎並不重要,它是按字母順序排列的(例如,函數按字母順序排列在函數之前和之後)。將DLL加載到depends.exe顯示有一個導出,但試圖rundll32它無法找到該導出。更改名稱可以解決問題。另外,有時你可以添加另一個函數,失敗的函數會成功,但是你剛添加的函數會失敗。

下面是我已經做了什麼來解決這個問題:我寫了一個C++程序加載編譯的自定義操作並驗證導出。然後我寫了一個單元測試,它在自定義操作中驗證了所有的導出。這顯然不能解決問題,但至少你會有單元測試失敗,並知道你的安裝程序已損壞。這裏的C++代碼,如果你有興趣:

typedef int(__stdcall *CustomActionProc)(HANDLE); 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    if (argc != 3) 
    { 
     _tprintf(_T("Parameters: DLL, EntryPoint\n")); 
     return 1; 
    } 

    LPCTSTR dllName = argv[1]; 
    LPCTSTR entryPoint = argv[2]; 

    HMODULE hLib = LoadLibrary(dllName); 
    if (hLib == NULL) 
    { 
     _tprintf(_T("Error loading %s\n"), dllName); 
     return 1; 
    } 

    CustomActionProc procAddress = 
     (CustomActionProc) GetProcAddress(hLib, CStringA(entryPoint)); 
    if (procAddress == NULL) 
    { 
     _tprintf(_T("Error locating entrypoint %s\n"), entryPoint); 
     return 1; 
    } 

    return 0; 
} 

而且單元測試是:

[TestMethod] 
    public void TestCustomActionCanBeInvoked() 
    { 
     var asm1 = typeof(MyCustomActionsClass).Assembly; 
     var methods = asm1.GetTypes().SelectMany(t => 
      t.GetMethods().Where(m => m.GetCustomAttributes(false) 
        .Where(a => a.GetType().Name == "CustomActionAttribute").Any())); 

     var binFolder = (new FileInfo(this.GetType().Assembly.Location)).DirectoryName; 
     var customActionsSfx = Path.Combine(binFolder, "MyCustomAction.CA.dll"); 
     var testMsiExport = Path.Combine(binFolder, "TestMsiExport.exe"); 

     foreach (var m in methods) 
     { 
      Trace.WriteLine("Method Name: " + m.Name); 

      var p = Process.Start(new ProcessStartInfo() 
      { 
       FileName = testMsiExport, 
       Arguments = "\"" + customActionsSfx + "\" " + m.Name, 
       UseShellExecute = false, 
       RedirectStandardOutput = true, 
      }); 

      p.OutputDataReceived += (s, d) => Trace.WriteLine(d.Data); 
      p.BeginOutputReadLine(); 
      p.WaitForExit(); 

      if (p.ExitCode != 0) 
      { 
       Assert.Fail("Bad Sfx export detected! Export name: " + m.Name); 
      } 
     } 
    } 

希望這可以幫助別人在我的處境。這是一個非常令人沮喪的一天,試圖指出這一點。

相關問題