Wix自定义Action发送HTTP Post失效,疑System.Net.Http引用问题求助
Since your code works in a standalone project but fails in the MSI context, the issue almost certainly lies in how the System.Net.Http assembly is referenced, deployed, or resolved at runtime during installation. Here’s a step-by-step breakdown of what to check:
1. Align .NET Framework/Version and Reference Style
- For .NET Framework projects: Avoid using the NuGet
System.Net.Httppackage if possible. The assembly is included natively in .NET Framework 4.5+, but the NuGet version can introduce version conflicts. If you must use the NuGet package (e.g., for newer features), ensure:- The package’s Copy Local property is set to
True(right-click the reference in your custom action project → Properties). This ensures the DLL is copied to your output directory. - Your custom action project targets a .NET Framework version compatible with Wix (Wix v3.x supports .NET Framework 4.0+; v4.x works with .NET Core/.NET 5+).
- The package’s Copy Local property is set to
- For .NET Core/.NET 5+ projects: Use the WixToolset.Dtf.CustomAction NuGet package, and configure your custom action as a self-contained deployment if the target machine might not have the runtime installed. This bundles all necessary dependencies (including
System.Net.Http) with your custom action.
2. Ensure the Assembly is Deployed with the MSI
The System.Net.Http DLL needs to be accessible when the custom action runs. Here’s how to ensure that:
- If you’re using the NuGet package and set
Copy Local = True, add the DLL to your Wix project as a binary or include it in the installation directory. For embedded dependencies, use tools like ILMerge to combine your custom action DLL withSystem.Net.Httpinto a single assembly (ILMerge works best with .NET Framework assemblies). - For .NET Core, set your custom action project to publish as self-contained, then reference the published DLL in your Wix
<Binary>element.
3. Check Wix Custom Action Configuration
Make sure your Wix markup correctly references the custom action and its dependencies:
- Define the custom action with the correct type (managed) and execution context. Example:
<Binary Id="MyCustomAction" SourceFile="path/to/your/custom/action.dll" /> <CustomAction Id="TrackInstallation" BinaryKey="MyCustomAction" DllEntry="YourMethodName" Execute="deferred" Impersonate="no" /> - If using .NET Core, add the
Runtimeattribute to specify the .NET version, or ensure the target machine has the required runtime installed.
4. Resolve Assembly Binding Conflicts
If the target machine has a different version of System.Net.Http than your custom action references, you’ll need binding redirects:
- Add binding redirects to your custom action project’s
app.configfile. Example:<dependentAssembly> <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" /> </dependentAssembly> - Ensure the config file is included with your custom action. Wix will automatically pick up the config if it’s in the same output directory as your DLL.
5. Debug to Confirm the Root Cause
To verify it’s a reference issue:
- Enable MSI logging by running:
msiexec /i YourInstaller.msi /l*v install.log - Look for errors like
Could not load file or assembly 'System.Net.Http' or one of its dependenciesin the log—this confirms a deployment/resolution problem. - Attach a debugger to the
msiexec.exeprocess when the custom action runs (set a breakpoint in your code and use Visual Studio’s Debug → Attach to Process).
6. Alternative: Use HttpWebRequest (Simpler for MSI Context)
If you’re still stuck, consider replacing HttpClient with HttpWebRequest—it’s part of the core .NET Framework, has fewer dependency issues, and works reliably in Wix custom actions for basic POST requests. Example snippet:
var request = (HttpWebRequest)WebRequest.Create("https://www.google-analytics.com/collect"); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; using (var streamWriter = new StreamWriter(request.GetRequestStream())) { string postData = "your_tracking_params_here"; streamWriter.Write(postData); } var response = (HttpWebResponse)request.GetResponse();
内容的提问来源于stack exchange,提问作者JED

