/
PackageInstallers.cs
154 lines (127 loc) · 5.28 KB
/
PackageInstallers.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Globalization;
using System.ComponentModel;
using System.IO;
using System.Windows.Media;
namespace InstallQueuer
{
public abstract class BasePackageInstaller : IPackageInstaller
{
public BasePackageInstaller(string FilePath) { _FilePath = FilePath; }
private readonly string _FilePath;
public string FilePath { get { return _FilePath; } }
public abstract PackageInstallerSupportedFeatures SupportedFeatures {get;}
public abstract void InstallPackage(Dictionary<PackageInstallerSupportedFeatures, object> options);
public virtual ImageSource Icon {
get { return null; }
}
public abstract string UserFriendlyDescription { get; }
protected static int launchProgramAndWait(string ExeName, string Params)
{
var psi = new ProcessStartInfo(ExeName, Params);
psi.EnvironmentVariables["REBOOT"] = "ReallySuppress";
var proc = Process.Start(psi);
proc.WaitForExit();
return proc.ExitCode;
}
}
[Export(typeof(IPackageInstallerFactory))]
public class MsiPackageInstallerFactory : IPackageInstallerFactory
{
public int AffinityForPackage(string FilePath)
{
return (FilePath.ToLowerInvariant().EndsWith(".msi") ? 5 : 0);
}
public IPackageInstaller CreateInstallerForPackage(string FilePath)
{
return new MsiPackageInstaller(FilePath);
}
}
public class MsiPackageInstaller : BasePackageInstaller
{
public MsiPackageInstaller(string FilePath) : base(FilePath) {}
public override PackageInstallerSupportedFeatures SupportedFeatures {
get {
return PackageInstallerSupportedFeatures.UnattendInstall;
}
}
public override string UserFriendlyDescription {
get {
// TODO: No idea how to do this yet, probably have to P/Invoke MSI...
return "Unknown";
}
}
public override void InstallPackage(Dictionary<PackageInstallerSupportedFeatures, object> Options)
{
string quiet_option = (Options.ContainsKey(PackageInstallerSupportedFeatures.UnattendInstall) ?
" /qn " : "");
string msiexec_params = String.Format(CultureInfo.InvariantCulture, "/I \"{0}\" {1} /norestart",
FilePath, quiet_option);
int retcode = launchProgramAndWait(@"%SystemRoot%\System32\MsiExec.exe", msiexec_params);
// MsiExec returns Win32 error codes
if (retcode != 0)
throw new Win32Exception(retcode);
}
}
[Export(typeof(IPackageInstallerFactory))]
public class VsPackageInstallerFactory : IPackageInstallerFactory
{
public int AffinityForPackage(string FilePath)
{
var di = new DirectoryInfo(Path.GetDirectoryName(FilePath));
bool is_this_vs = di.GetFiles().Select(x => x.FullName.ToLowerInvariant())
.Any(x => x.EndsWith("vs_setup.msi"));
return (is_this_vs ? 10 : 0);
}
public IPackageInstaller CreateInstallerForPackage(string FilePath)
{
// VS's *real* setup program is actually buried under a folder - if they give us the root
// installer, let's find the real one
var setup_path = Path.Combine(Path.GetDirectoryName(FilePath),
"Setup", "Setup.exe");
return new DummyExePackageInstaller(setup_path, " /full /noreboot ", " /q ");
}
}
[Export(typeof(IPackageInstallerFactory))]
public class DummyExePackageInstallerFactory : IPackageInstallerFactory
{
public int AffinityForPackage(string FilePath)
{
return (FilePath.ToLowerInvariant().EndsWith(".exe") ? 1 : 0);
}
public IPackageInstaller CreateInstallerForPackage(string FilePath)
{
return new DummyExePackageInstaller(FilePath, "", "");
}
}
public class DummyExePackageInstaller : BasePackageInstaller
{
readonly string quietSwitch;
readonly string exeParams;
public DummyExePackageInstaller(string FilePath, string Params, string QuietSwitch) : base(FilePath) { exeParams = Params; quietSwitch = QuietSwitch; }
public override PackageInstallerSupportedFeatures SupportedFeatures {
get {
return (String.IsNullOrEmpty(quietSwitch) ? 0 : PackageInstallerSupportedFeatures.UnattendInstall);
}
}
public override string UserFriendlyDescription {
get {
var fvi = FileVersionInfo.GetVersionInfo(FilePath);
return String.Format("{0} ({1})", fvi.ProductName, fvi.ProductVersion);
}
}
public override void InstallPackage(Dictionary<PackageInstallerSupportedFeatures, object> Options)
{
int retcode = launchProgramAndWait(FilePath, exeParams ?? "");
// Who knows what this means...
if (retcode != 0)
throw new Exception("Failed install");
}
}
}
// vim: ts=4:sts=4:sw=4:et