Execute MSI package in a custom Burn Bootstrapper Application - c#

I am bundling a MSI package with the .NET 4.0 framework installer in Burn. Since i do not like the userinterface Burn applies, i have written my own custom Bootstrapper Application. The .NET framework is installed correctly, if it is not already installed. But i can not figure out how to install the MSI package. This is the code i have for my custom BA, i have checked that it gets executed.
public class ShopProtectBA : BootstrapperApplication
{
protected override void Run()
{
//Here i would like to run the bundled MSI package.
Engine.Quit(0);
}
}
The documentation on this is sparse. Should i not install the package in Run() ? How do this ting work?
Edit: I forgot to mention that is is a custom Managed Bootstrapper Application. If it makes any difference.
The best i can come up with is this:
var pl = new PlanMsiFeatureEventArgs("MyMsiPackage", "Complete", FeatureState.Local);
Engine.Detect();
OnPlanMsiFeature(pl);
Engine.Plan(LaunchAction.Install);
Engine.Elevate(FindWindow(null, "Setup"));
Engine.Apply(FindWindow(null, "Setup"));
But it results only in a window telling me that the installation is prepared. Then i closes and nothing more happends.

There's more to it than that: You have to ask the engine to detect machine state, plan package actions, and apply them. Take a look at the source code for the WiX BA itself: src\Setup\WixBA.

Related

Is calling System.Diagnostics.Process.Start() truly problematic?

In the Validation Result that I get when readying my app for submission to the Microsoft Store (which my app "PASSED WITH WARNINGS"), I got this "Fail" under the "Package Sanity Test" section:
The code which contains such a call is:
private void myMapsHelpToolStripMenuItem_Click(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("https://ramblingnotesofageezer.substack.com/p/map-o-matic-overview");
}
I am using that code due to the recommendation to do so here. How do I start a process from C#?
Is this truly a problem? If so, what should I use instead of the call to System.Diagnostics.Process.Start()?
I find it odd that it is classified as a failed part of the test, yet the overall results are that my app passed (albeit with warnings).
UPDATE
I checked out the link in the comment from Codexer, where it says, "Starting a utility can often provide a convenient way to obtain information from the operating system, access the registry, or access system capabilities. However, you can use UWP APIs to accomplish these sorts of tasks instead."
If this is the solution, do the UWP APIs have an equivalent to System.Diagnostics.Process.Start()?
UPDATE 2
I followed the steps in the answer, but the solution still doesn't compile, due to an error with this line of code:
await Windows.System.Launcher.LaunchUriAsync(uri);
In fact, even when I comment out the offending line, the project will no longer compile, but doesn't give me any information about how to solve the problem, just this:
I set the Package Management Format to PackageReference, and installed version 10.0.18362.2005 of Microsoft.Windows.SDK.Contracts, but it is complaining about needing a package reference...?!? I tried adding using Windows.System;
and using Microsoft.Windows.SDK.Contracts; but neither is recognized.
The package is installed for the project, as you can see here:
UPDATE 3
Regarding the "Must Use Package Reference" err msg, I have three questions revolving around what I see here:
The verbiage below Microsoft.Windows.SDK.Contracts says I can update versions of this package - should I?
I do not see a Reference to Microsoft.Windows.SDK.Contracts in my project's References, although it has been installed. Do I need to add one - if so, from where?
The context menu on my References affords me the ability to "Migrate packages.config to PackageReference..." should I do that?
If you were developing an uwp application, for opening open a web uri, it is recommended to use Launcher.LaunchUriAsync(Uri) method instead, this method starts the default browser to open the specified URI.
For example:
private async void button_Click(object sender, RoutedEventArgs e)
{
Uri uri = new Uri("http://www.google.com");
await Windows.System.Launcher.LaunchUriAsync(uri);
}
Update:
As Codexer mentioned, you could refer to this document to use uwp api in winform app.
I have created a winform project, its target framework is .Net Framework4.8. For earlier versions of .NET(.NET Core 3.x, .NET 5 Preview 7 (or earlier), or .NET Framework), you could refer to my steps.
1.Click Tools->NuGet Package Manager-> Package Manager Settings-> Change Default package management format to PackageReference. As follows:
2.Install the Microsoft.Windows.SDK.Contracts package, note that you need to install the appropriate version. Please check the corresponding version below. (Installation details: Right click Reference-> Manage NuGet Packages->Browse->Search Microsoft.Windows.SDK.Contracts->install)
10.0.19041.xxxx: Choose this for Windows 10, version 2004, version 20H2
10.0.18362.xxxx: Choose this for Windows 10, version 1903.
10.0.17763.xxxx: Choose this for Windows 10, version 1809.
10.0.17134.xxxx: Choose this for Windows 10, version 1803.
3.Run the project

WebApi controller tests method not found

I have a very simple WebAPI 2 controller running on .NET Framework 4.6.2, that looks like this:
[RoutePrefix("Invitations")]
public class InvitationsController : CqrsApiController
{
[HttpPost, Route("Clients/{id:long}/Actions/Cancel")]
public IHttpActionResult PostClientInvitationCancel(long id, [FromBody] ClientInvitationCancelCommand command)
{
Execute(command);
return SeeOther("Invitations/Clients/{0}", id);
}
}
and am trying to write an NUnit test for it, like this:
[TestFixture]
public class WhenExecutingAValidCommand
{
[Test]
public void ItShouldReturnARedirect()
{
var dispatcher = Substitute.For<ICqrsDispatcher>();
var urlHelper = Substitute.For<UrlHelper>();
urlHelper.Link(Arg.Any<string>(), Arg.Any<object>()).Returns("https://tempuri.org/");
var sut = new InvitationsController(dispatcher);
sut.Request = new HttpRequestMessage();
sut.Configuration = new HttpConfiguration();
sut.Url = urlHelper;
var response = sut.PostClientInvitationCancel(1, new ClientInvitationCancelCommand());
response.Should().BeOfType<SeeOtherRedirectResult>();
}
}
```
However, when I run the test, I get the following error:
System.MissingMethodException : Method not found: 'Void System.Web.Http.ApiController.set_Request(System.Net.Http.HttpRequestMessage)'.
at ApiProjectTests.InvitationsControllerTests.WhenExecutingAValidCommand.ItShouldReturnARedirect()
The same code seems to work fine in similar projects based on .NET Framework 4.5.1, so I'm wondering if there's some sort of DLL hell going on here. System.Web.Http is using Microsoft.AspNet.WebApi.Core.5.2.3, whereas System.Net.Http is coming from the GAC (well, C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Http.dll to be more precise).
Update: if I try to debug into the unit test, the error occurs before I even enter the method. So although VS2017 compiles the tests just fine, when the test runner fires up, then everything falls apart. Sounds more like DLL hell to me.
Update 2: if I comment out the setting of the request, then I can debug into the test method. If I then put in a breakpoint, and then use the Immediate window to directly set the request property, it works, and there is no Method not found error. I also disabled Resharper and used VS2017's Test Explorer to run the tests, in case R# was caching something, but it made no difference.
It looks like my problem is indeed DLL hell, more specifically the DLL hell referenced by https://github.com/dotnet/corefx/issues/25773. The issue is caused by other NuGet packages that contain references to the newer version of System.Net.Http (4.2.0.0). The current solution appears to be to add a binding redirect to downgrade the assembly version to the expected version (4.0.0.0), but so far that has not helped me.
The solution that did work for me was to install the latest NuGet package of System.Net.Http, and use assembly binding redirects in my test project to ensure that it used the 4.2.0.0 version instead of 4.0.0.0.
This is often caused by early versions of nuget packages targeting .NET standard, which have dependencies on OOB ("out-of-band") packages. OOB packages are a kind of polyfill for dlls that are part of .NET framework but not .NET standard. Here is a very good explanation of what happened. In my case, the following helped:
I identified the nuget package that had a dependency on the system.net.http 4.2.0 nuget package, and upgrade that package.
The dependency was no longer present in the upgraded package, so i could uninstall the system.net.http 4.2.0 nuget package.
The upgraded package of course still expects the reference to the system.net.http 4.0.0 assembly, so in case of doubt, you may reinstall the upgraded package to make sure that the assembly reference is in your *.csproj file.

Opening a solution with msbuildworkspace gives diagnostics errors without details

I am trying to analyse a solution with Roslyn, with MSBuildWorkspace.
The solution is a new solution, with 2 class library projects in them, one referencing the other.
They are created in Visual Studio 2017, .Net 4.6.2.
When I open the solution, I receive two generic errors in workspace.Diagnostics, both are :
Msbuild failed when processing the file 'PathToProject'
There is nothing more in the diagnostics or output window, to indicate WHY it failed to process the project file.
The code for opening the solution:
namespace RoslynAnalyse
{
class Program
{
static void Main(string[] args)
{
LocalAnalysis();
}
private static void LocalAnalysis()
{
var workspace = MSBuildWorkspace.Create();
var solution = workspace.OpenSolutionAsync(#"D:\Code\Roslyn\RoslynAnalyse\SolutionToAnalyse\SolutionToAnalyse.sln").Result;
var workspaceDiagnostics = workspace.Diagnostics;
}
}
}
The version of Microsoft.CodeAnalysis is 2.0.0.0.
Does anybody have any idea why MSBuild failed, how I can get more information ?
When MSBuildWorkspace fails to open a project or solution this way, it is almost always because the application using MSBuildWorkspace does not include the same binding redirects that msbuild.exe.config has in it.
MSBuild uses binding redirects to allow tasks (typically already compiled C# code using possibly different versions of msbuild API libraries) to all use the current msbuild API's. Otherwise, msbuild gets runtime load failures.
The solution is to add an app.config file to your project and copy the binding redirects (the assemblyBinding section of the msbuild.exe.config file) into your file.

Install MVVMCross plugin in UWP failure

i am trying to install MVVMCross plugin in UWP project but it seems to fail.
in the PCL it seems to be working fine, but in the UWP I'm expecting that the plugin will create a Bootstrap folder and it doesn't happen.
I even started a new project from scratch named it "TipCalc.WindowsUWP", installed the MVVMCross and then the JSON plugin using NuGet and nothing happens.
the output of the plugin installation looks fine:
Restoring packages for 'TipCalc.WindowsUWP'.
Restoring packages for C:\Users\kayce\Documents\Visual Studio 2015\Projects\TenBisServer\MvvmCross\TipCalc\TipCalc.WindowsUWP\project.json...
Package restore completed successfully for 'TipCalc.WindowsUWP'.
Successfully installed 'MvvmCross.Plugin.Json 4.2.3' to TipCalc.WindowsUWP
========== Finished ==========
what I am missing ?
This is expected behavior, as a UWP project uses a project.json (NuGet 3) template. Currently all additional content and scripting specified in the NuGet package with have no affect on your project when including a package (See Changes affecting existing packages).
You will have to manually add the bootstrap folder and relevant plugin bootstrap .cs file, or you can register the interface and implementation of the plugin in your Setup.cs.
Bootstrap Approach:
using MvvmCross.Platform.Plugins;
namespace <<YOUR_NAMESSPACE>>.Bootstrap
{
public class JsonPluginBootstrap
: MvxPluginBootstrapAction<MvvmCross.Plugins.Json.PluginLoader>
{
}
}
Setup.cs Approach:
protected override void InitializeLastChance()
{
base.InitializeLastChance();
Mvx.RegisterSingleton<IMvxJsonConverter>(new MvxJsonConverter());
}

The server factory could not be located for the given input: Microsoft.Owin.Host.HttpListener

I have implemente signalR in window service.
private IDisposable SignalR { get; set; }
public void Configuration(IAppBuilder app)
{
var hubconfig=new Microsoft.AspNet.SignalR.HubConfiguration();
hubconfig.EnableJSONP = true;
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR(hubconfig);
}
private void StartSignalRServer(StringBuilder sbLog)
{
try
{
this.SignalR = WebApp.Start(ServerURI); //This throws exception
//this.SignalR= WebApp.Start<Startup>(ServerURI);
sbLog.Append(string.Format("{0}--------SignalR Server Started------",Environment.NewLine));
}
catch (Exception ex)
{
sbLog.Append(string.Format("{0}Exception in StartSignalRServer=>{1}", Environment.NewLine,ex.Message));
}
}
Exception:The server factory could not be located for the given input:
Microsoft.Owin.Host.HttpListener
The Microsoft.Owin.Host.HttpListener assembly is a runtime reference in WebApp.Start. You need to include it in the project's references for it to be available for loading. Check the bin\Debug (etc) directory to make sure it's included. May as well add it as a nuget dependency as well.
Install the package:
PM> Install-Package Microsoft.Owin.Host.HttpListener
Install the Microsoft.Owin.Host.HttpListener package from Nuget using:
PM> Install-Package Microsoft.Owin.Host.HttpListener
(unlike an earlier answer you should avoid using -IncludePrerelease in production code)
Hello for same error message but in slithly different context that i have encountered:
Due to stupid referencing optimization which is totally immature regarding reflection. It happens that MsBuild do not copies the Microsoft.Owin.Host.HttpListener.dll in your startup project if it references another project which uses Owin.
In my case I have the error messsage mentioned above and opted for explicit reference in project using Owin by adding explicit use of the problematic dll so that msbuild sees a reference needed so Microsoft.Owin.Host.HttpListener.dll will be copied (not needed for other dll) -This issue come from the fact that owin stuff does reflection inside itself leaving msbuild completely dummy by removing this dll-:
using Microsoft.Owin.Host.HttpListener;
...
_log.Debug("Loading type: "+ typeof(OwinHttpListener) + "..."); // Hack to force copy of Microsoft.Owin.Host.HttpListener.dll on target referencing project
I encountered same error.
In project A -- I am starting owin web service using WebApp.Start() in a function.
In Project B -- I am calling project A's function here. Unfortunately Project B is not my .Net solution's startup project.
Project C is my .Net Solution startup project.
If I Install nuget package using command Install-Package Microsoft.Owin.Host.HttpListener in solution's start up project i.e Project, C it works fine. If I do the same in Project B it does not work. So be careful while installing nuget package.

Categories