aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.WixBA/WixBA.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/WixToolset.WixBA/WixBA.cs216
-rw-r--r--src/WixToolset.WixBA/WixBA.csproj64
2 files changed, 280 insertions, 0 deletions
diff --git a/src/WixToolset.WixBA/WixBA.cs b/src/WixToolset.WixBA/WixBA.cs
new file mode 100644
index 00000000..fb69a346
--- /dev/null
+++ b/src/WixToolset.WixBA/WixBA.cs
@@ -0,0 +1,216 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.UX
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Diagnostics;
8 using System.IO;
9 using System.Net;
10 using System.Text;
11 using System.Windows.Input;
12 using Threading = System.Windows.Threading;
13 using WinForms = System.Windows.Forms;
14
15 using WixToolset.Bootstrapper;
16
17 /// <summary>
18 /// The WiX toolset user experience.
19 /// </summary>
20 public class WixBA : BootstrapperApplication
21 {
22 /// <summary>
23 /// Gets the global model.
24 /// </summary>
25 static public Model Model { get; private set; }
26
27 /// <summary>
28 /// Gets the global view.
29 /// </summary>
30 static public RootView View { get; private set; }
31 // TODO: We should refactor things so we dont have a global View.
32
33 /// <summary>
34 /// Gets the global dispatcher.
35 /// </summary>
36 static public Threading.Dispatcher Dispatcher { get; private set; }
37
38 /// <summary>
39 /// Launches the default web browser to the provided URI.
40 /// </summary>
41 /// <param name="uri">URI to open the web browser.</param>
42 public static void LaunchUrl(string uri)
43 {
44 WixBA.UseShellExecute(uri);
45 }
46
47 /// <summary>
48 /// Open a log file.
49 /// </summary>
50 /// <param name="uri">URI to a log file.</param>
51 internal static void OpenLog(Uri uri)
52 {
53 WixBA.UseShellExecute(uri.ToString());
54 }
55
56 /// <summary>
57 /// Open a log folder.
58 /// </summary>
59 /// <param name="string">path to a log folder.</param>
60 internal static void OpenLogFolder(string logFolder)
61 {
62 WixBA.UseShellExecute(logFolder);
63 }
64
65 /// <summary>
66 /// Open a log folder.
67 /// </summary>
68 /// <param name="uri">path to a log folder.</param>
69 private static void UseShellExecute(string path)
70 {
71 // Switch the wait cursor since shellexec can take a second or so.
72 System.Windows.Input.Cursor cursor = WixBA.View.Cursor;
73 WixBA.View.Cursor = System.Windows.Input.Cursors.Wait;
74 Process process = null;
75 try
76 {
77 process = new Process();
78 process.StartInfo.FileName = path;
79 process.StartInfo.UseShellExecute = true;
80 process.StartInfo.Verb = "open";
81
82 process.Start();
83 }
84 finally
85 {
86 if (null != process)
87 {
88 process.Dispose();
89 }
90 // back to the original cursor.
91 WixBA.View.Cursor = cursor;
92 }
93 }
94
95 /// <summary>
96 /// Starts planning the appropriate action.
97 /// </summary>
98 /// <param name="action">Action to plan.</param>
99 public static void Plan(LaunchAction action)
100 {
101 WixBA.Model.PlannedAction = action;
102 WixBA.Model.Engine.Plan(WixBA.Model.PlannedAction);
103 }
104
105 public static void PlanLayout()
106 {
107 // Either default or set the layout directory
108 if (String.IsNullOrEmpty(WixBA.Model.Command.LayoutDirectory))
109 {
110 WixBA.Model.LayoutDirectory = Directory.GetCurrentDirectory();
111
112 // Ask the user for layout folder if one wasn't provided and we're in full UI mode
113 if (WixBA.Model.Command.Display == Display.Full)
114 {
115 WixBA.Dispatcher.Invoke((Action)delegate()
116 {
117 WinForms.FolderBrowserDialog browserDialog = new WinForms.FolderBrowserDialog();
118 browserDialog.RootFolder = Environment.SpecialFolder.MyComputer;
119
120 // Default to the current directory.
121 browserDialog.SelectedPath = WixBA.Model.LayoutDirectory;
122 WinForms.DialogResult result = browserDialog.ShowDialog();
123
124 if (WinForms.DialogResult.OK == result)
125 {
126 WixBA.Model.LayoutDirectory = browserDialog.SelectedPath;
127 WixBA.Plan(WixBA.Model.Command.Action);
128 }
129 else
130 {
131 WixBA.View.Close();
132 }
133 }
134 );
135 }
136 }
137 else
138 {
139 WixBA.Model.LayoutDirectory = WixBA.Model.Command.LayoutDirectory;
140 WixBA.Plan(WixBA.Model.Command.Action);
141 }
142 }
143
144 /// <summary>
145 /// Thread entry point for WiX Toolset UX.
146 /// </summary>
147 protected override void Run()
148 {
149 this.Engine.Log(LogLevel.Verbose, "Running the WiX BA.");
150 WixBA.Model = new Model(this);
151 WixBA.Dispatcher = Threading.Dispatcher.CurrentDispatcher;
152 RootViewModel viewModel = new RootViewModel();
153
154 // Kick off detect which will populate the view models.
155 this.Engine.Detect();
156
157 // Create a Window to show UI.
158 if (WixBA.Model.Command.Display == Display.Passive ||
159 WixBA.Model.Command.Display == Display.Full)
160 {
161 this.Engine.Log(LogLevel.Verbose, "Creating a UI.");
162 WixBA.View = new RootView(viewModel);
163 WixBA.View.Show();
164 }
165
166 Threading.Dispatcher.Run();
167
168 this.PostTelemetry();
169 this.Engine.Quit(WixBA.Model.Result);
170 }
171
172 private void PostTelemetry()
173 {
174 string result = String.Concat("0x", WixBA.Model.Result.ToString("x"));
175
176 StringBuilder telemetryData = new StringBuilder();
177 foreach (KeyValuePair<string, string> kvp in WixBA.Model.Telemetry)
178 {
179 telemetryData.AppendFormat("{0}={1}+", kvp.Key, kvp.Value);
180 }
181 telemetryData.AppendFormat("Result={0}", result);
182
183 byte[] data = Encoding.UTF8.GetBytes(telemetryData.ToString());
184
185 try
186 {
187 HttpWebRequest post = WixBA.Model.CreateWebRequest(String.Format(WixDistribution.TelemetryUrlFormat, WixBA.Model.Version.ToString(), result));
188 post.Method = "POST";
189 post.ContentType = "application/x-www-form-urlencoded";
190 post.ContentLength = data.Length;
191
192 using (Stream postStream = post.GetRequestStream())
193 {
194 postStream.Write(data, 0, data.Length);
195 }
196
197 HttpWebResponse response = (HttpWebResponse)post.GetResponse();
198 }
199 catch (ArgumentException)
200 {
201 }
202 catch (FormatException)
203 {
204 }
205 catch (OverflowException)
206 {
207 }
208 catch (ProtocolViolationException)
209 {
210 }
211 catch (WebException)
212 {
213 }
214 }
215 }
216}
diff --git a/src/WixToolset.WixBA/WixBA.csproj b/src/WixToolset.WixBA/WixBA.csproj
new file mode 100644
index 00000000..6858b172
--- /dev/null
+++ b/src/WixToolset.WixBA/WixBA.csproj
@@ -0,0 +1,64 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
4 <PropertyGroup>
5 <ProjectGuid>{7C27518B-84AD-4679-8EF4-29DF552CF1AC}</ProjectGuid>
6 <AssemblyName>WixBA</AssemblyName>
7 <OutputType>Library</OutputType>
8 <RootNamespace>WixToolset.UX</RootNamespace>
9 </PropertyGroup>
10 <ItemGroup>
11 <Compile Include="Hresult.cs" />
12 <Compile Include="Model.cs" />
13 <Compile Include="BrowserProperties.cs" />
14 <Compile Include="NewsItem.cs" />
15 <Compile Include="ProgressViewModel.cs" />
16 <Compile Include="RelayCommand.cs" />
17 <Compile Include="InstallationViewModel.cs" />
18 <Page Include="Styles.xaml">
19 <Generator>MSBuild:Compile</Generator>
20 <SubType>Designer</SubType>
21 </Page>
22 <Page Include="RootView.xaml">
23 <Generator>MSBuild:Compile</Generator>
24 <SubType>Designer</SubType>
25 </Page>
26 <Compile Include="PropertyNotifyBase.cs" />
27 <Compile Include="RootView.xaml.cs">
28 <DependentUpon>RootView.xaml</DependentUpon>
29 </Compile>
30 <Compile Include="RootViewModel.cs" />
31 <Compile Include="UpdateViewModel.cs" />
32 <Compile Include="WindowProperties.cs" />
33 <Compile Include="WixBA.cs" />
34 <Compile Include="Properties\AssemblyInfo.cs" />
35 <None Include="WixBA.BootstrapperCore.config">
36 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
37 <SubType>Designer</SubType>
38 </None>
39 </ItemGroup>
40 <ItemGroup>
41 <Reference Include="PresentationCore" />
42 <Reference Include="PresentationFramework" />
43 <Reference Include="System" />
44 <Reference Include="System.ComponentModel.DataAnnotations" />
45 <Reference Include="System.Core" />
46 <Reference Include="System.Drawing">
47 <Private>False</Private>
48 </Reference>
49 <Reference Include="System.ServiceModel" />
50 <Reference Include="System.Windows.Forms" />
51 <Reference Include="System.Xml.Linq" />
52 <Reference Include="System.Xml" />
53 <Reference Include="System.Xaml" />
54 <Reference Include="WindowsBase" />
55 <ProjectReference Include="..\..\ext\BalExtension\mba\core\core.csproj" />
56 </ItemGroup>
57 <ItemGroup>
58 <Resource Include="Resources\logo-white-hollow.png" />
59 </ItemGroup>
60 <ItemGroup>
61 <Resource Include="Resources\logo-black-hollow.png" />
62 </ItemGroup>
63 <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), wix.proj))\tools\WixBuild.targets" />
64</Project> \ No newline at end of file