Skip to content

Commit

Permalink
WIP: MSI installer #723
Browse files Browse the repository at this point in the history
  • Loading branch information
develar committed Oct 23, 2017
1 parent fc8fb9e commit 9596448
Show file tree
Hide file tree
Showing 23 changed files with 446 additions and 178 deletions.
4 changes: 4 additions & 0 deletions .idea/dictionaries/develar.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"temp-file": "^2.0.3",
"tunnel-agent": "^0.6.0",
"update-notifier": "^2.3.0",
"yargs": "^9.0.1"
"yargs": "^10.0.3"
},
"devDependencies": {
"@develar/gitbook": "3.2.10",
Expand Down
97 changes: 4 additions & 93 deletions packages/builder-util-runtime/src/uuid.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import { createHash, randomBytes } from "crypto"

// error codes
const invalidNamespace =
"options.namespace must be a string or a Buffer " +
"containing a valid UUID, or a UUID object"

const invalidName =
"options.name must be either a string or a Buffer"

Expand Down Expand Up @@ -42,10 +37,8 @@ export class UUID {
private version: number

// from rfc4122#appendix-C
static readonly DNS = new UUID("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
static readonly URL = new UUID("6ba7b811-9dad-11d1-80b4-00c04fd430c8")
static readonly OID = new UUID("6ba7b812-9dad-11d1-80b4-00c04fd430c8")
static readonly X500 = new UUID("6ba7b814-9dad-11d1-80b4-00c04fd430c8")
static readonly OID = UUID.parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")

constructor(uuid: Buffer | string) {
const check = UUID.check(uuid)
Expand All @@ -67,7 +60,7 @@ export class UUID {
return uuidTimeBased(randomHost)
}

static v5(name: string | Buffer, namespace: string | Buffer | UUID) {
static v5(name: string | Buffer, namespace: Buffer) {
return uuidNamed(name, "sha1", 0x50, namespace)
}

Expand Down Expand Up @@ -250,24 +243,11 @@ function uuidTimeBased(nodeId: Buffer, encoding: UuidEncoding = UuidEncoding.ASC
}

// v3 + v5
function uuidNamed(name: string | Buffer, hashMethod: string, version: number, namespace: string | Buffer | UUID, encoding: UuidEncoding = UuidEncoding.ASCII) {
function uuidNamed(name: string | Buffer, hashMethod: string, version: number, namespace: Buffer, encoding: UuidEncoding = UuidEncoding.ASCII) {
const hash = createHash(hashMethod)

if (typeof namespace === "string") {
if (!UUID.check(namespace)) {
throw new Error(invalidNamespace)
}
namespace = UUID.parse(namespace)
}
else if (namespace instanceof UUID) {
namespace = namespace.toBuffer()
}
else if (!(Buffer.isBuffer(namespace)) || namespace.length !== 16) {
throw new Error(invalidNamespace)
}

const nameIsNotAString = typeof name !== "string"
if (nameIsNotAString && !(Buffer.isBuffer(name))) {
if (nameIsNotAString && !Buffer.isBuffer(name)) {
throw new Error(invalidName)
}

Expand Down Expand Up @@ -303,75 +283,6 @@ function uuidNamed(name: string | Buffer, hashMethod: string, version: number, n
return result
}

// v4
// function uuidRandom(arg1, arg2) {
//
// const options = arg1 || {}
// const callback = typeof arg1 === "function" ? arg1 : arg2
//
// const buffer = crypto.randomBytes(16)
//
// buffer[6] = (buffer[6] & 0x0f) | 0x40
// buffer[8] = (buffer[8] & 0x3f) | 0x80
//
// let result
// switch (options.encoding && options.encoding[0]) {
// case "b":
// case "B":
// result = buffer
// break
// case "o":
// case "U":
// result = new UUID(buffer)
// break
// default:
// result = byte2hex[buffer[0]] + byte2hex[buffer[1]] +
// byte2hex[buffer[2]] + byte2hex[buffer[3]] + "-" +
// byte2hex[buffer[4]] + byte2hex[buffer[5]] + "-" +
// byte2hex[(buffer[6] & 0x0f) | 0x40] +
// byte2hex[buffer[7]] + "-" +
// byte2hex[(buffer[8] & 0x3f) | 0x80] +
// byte2hex[buffer[9]] + "-" +
// byte2hex[buffer[10]] + byte2hex[buffer[11]] +
// byte2hex[buffer[12]] + byte2hex[buffer[13]] +
// byte2hex[buffer[14]] + byte2hex[buffer[15]]
// break
// }
// if (callback) {
// setImmediate(function() {
// callback(null, result)
// })
// } else {
// return result
// }
// }

// v4 fast
// function uuidRandomFast() {
//
// const r1 = Math.random() * 0x100000000
// const r2 = Math.random() * 0x100000000
// const r3 = Math.random() * 0x100000000
// const r4 = Math.random() * 0x100000000
//
// return byte2hex[ r1 & 0xff] +
// byte2hex[ r1 >>> 8 & 0xff] +
// byte2hex[ r1 >>> 16 & 0xff] +
// byte2hex[ r1 >>> 24 & 0xff] + "-" +
// byte2hex[ r2 & 0xff] +
// byte2hex[ r2 >>> 8 & 0xff] + "-" +
// byte2hex[(r2 >>> 16 & 0x0f) | 0x40] +
// byte2hex[ r2 >>> 24 & 0xff] + "-" +
// byte2hex[(r3 & 0x3f) | 0x80] +
// byte2hex[ r3 >>> 8 & 0xff] + "-" +
// byte2hex[ r3 >>> 16 & 0xff] +
// byte2hex[ r3 >>> 24 & 0xff] +
// byte2hex[ r4 & 0xff] +
// byte2hex[ r4 >>> 8 & 0xff] +
// byte2hex[ r4 >>> 16 & 0xff] +
// byte2hex[ r1 >>> 24 & 0xff]
// }

function stringify(buffer: Buffer) {
return byte2hex[buffer[0]] + byte2hex[buffer[1]] +
byte2hex[buffer[2]] + byte2hex[buffer[3]] + "-" +
Expand Down
4 changes: 2 additions & 2 deletions packages/electron-builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"7zip-bin": "^2.2.7",
"async-exit-hook": "^2.0.1",
"bluebird-lst": "^1.0.5",
"chalk": "2.1.0",
"chalk": "2.1.0",
"chromium-pickle-js": "^0.2.0",
"cuint": "^0.2.2",
"app-package-builder": "0.0.0-semantic-release",
Expand All @@ -75,7 +75,7 @@
"sanitize-filename": "^1.6.1",
"semver": "^5.4.1",
"update-notifier": "^2.3.0",
"yargs": "^9.0.1",
"yargs": "^10.0.3",
"debug": "^3.1.0",
"asar-integrity": "0.0.0-semantic-release",
"lazy-val": "^1.0.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { bold } from "chalk"
import { ensureDir } from "fs-extra-p"
import * as path from "path"
import sanitizeFileName from "sanitize-filename"
import { quoteString } from "../targets/appx"
import { quoteString } from "../targets/AppxTarget"
import { getSignVendorPath } from "../windowsCodeSign"

/** @internal */
Expand Down
6 changes: 5 additions & 1 deletion packages/electron-builder/src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import { DmgOptions, MacConfiguration, MasConfiguration, PkgOptions } from "./op
import { PlatformSpecificBuildOptions } from "./options/PlatformSpecificBuildOptions"
import { SnapOptions } from "./options/SnapOptions"
import { SquirrelWindowsOptions } from "./options/SquirrelWindowsOptions"
import { AppXOptions, WindowsConfiguration } from "./options/winOptions"
import { WindowsConfiguration } from "./options/winOptions"
import { PlatformPackager } from "./platformPackager"
import { NsisOptions, NsisWebOptions, PortableOptions } from "./targets/nsis/nsisOptions"
import { MsiOptions } from "./options/MsiOptions"
import { AppXOptions } from "./options/AppXOptions"

/**
* Configuration Options
Expand Down Expand Up @@ -58,6 +60,8 @@ export interface Configuration extends PlatformSpecificBuildOptions {
readonly nsisWeb?: NsisWebOptions | null
readonly portable?: PortableOptions | null
readonly appx?: AppXOptions | null
/** @private */
readonly msi?: MsiOptions | null
readonly squirrelWindows?: SquirrelWindowsOptions | null

/**
Expand Down
4 changes: 3 additions & 1 deletion packages/electron-builder/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ export { Configuration, AfterPackContext, MetadataDirectories, Protocol, Release
export { PlatformSpecificBuildOptions, AsarOptions, FileSet } from "./options/PlatformSpecificBuildOptions"
export { FileAssociation } from "./options/FileAssociation"
export { MacConfiguration, DmgOptions, MasConfiguration, MacOsTargetName, PkgOptions, DmgContent, DmgWindow } from "./options/macOptions"
export { WindowsConfiguration, AppXOptions } from "./options/winOptions"
export { WindowsConfiguration } from "./options/winOptions"
export { AppXOptions } from "./options/AppXOptions"
export { MsiOptions } from "./options/MsiOptions"
export { NsisOptions, NsisWebOptions, PortableOptions, CommonNsisOptions } from "./targets/nsis/nsisOptions"
export { LinuxConfiguration, DebOptions, CommonLinuxOptions, LinuxTargetSpecificOptions, AppImageOptions } from "./options/linuxOptions"
export { SnapOptions } from "./options/SnapOptions"
Expand Down
52 changes: 52 additions & 0 deletions packages/electron-builder/src/options/AppXOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { TargetSpecificOptions } from "../core"

export interface AppXOptions extends TargetSpecificOptions {
/**
* The application id. Defaults to `identityName`. Can’t start with numbers.
*/
readonly applicationId?: string

/**
* The background color of the app tile. See [Visual Elements](https://msdn.microsoft.com/en-us/library/windows/apps/br211471.aspx).
* @default #464646
*/
readonly backgroundColor?: string | null

/**
* A friendly name that can be displayed to users. Corresponds to [Properties.DisplayName](https://msdn.microsoft.com/en-us/library/windows/apps/br211432.aspx).
* Defaults to the application product name.
*/
readonly displayName?: string | null

/**
* The name. Corresponds to [Identity.Name](https://msdn.microsoft.com/en-us/library/windows/apps/br211441.aspx). Defaults to the [application name](/configuration/configuration#Metadata-name).
*/
readonly identityName?: string | null

/**
* The Windows Store publisher. Not used if AppX is build for testing. See [AppX Package Code Signing](#appx-package-code-signing) below.
*/
readonly publisher?: string | null

/**
* A friendly name for the publisher that can be displayed to users. Corresponds to [Properties.PublisherDisplayName](https://msdn.microsoft.com/en-us/library/windows/apps/br211460.aspx).
* Defaults to company name from the application metadata.
*/
readonly publisherDisplayName?: string | null

/**
* The list of [supported languages](https://docs.microsoft.com/en-us/windows/uwp/globalizing/manage-language-and-region#specify-the-supported-languages-in-the-apps-manifest) that will be listed in the Windows Store.
* The first entry (index 0) will be the default language.
* Defaults to en-US if omitted.
*/
readonly languages?: Array<string> | string | null

/**
* @private
* @default false
*/
readonly electronUpdaterAware?: boolean

/** @private */
readonly makeappxArgs?: Array<string> | null
}
26 changes: 26 additions & 0 deletions packages/electron-builder/src/options/MsiOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { TargetSpecificOptions } from "../core"

export interface MsiOptions extends TargetSpecificOptions {
/**
* One-click installation.
* @default true
*/
readonly oneClick?: boolean

/***
* Install per all users (per-machine).
* @default true
*/
readonly perMachine?: boolean

/**
* The [upgrade code](https://msdn.microsoft.com/en-us/library/windows/desktop/aa372375(v=vs.85).aspx). Optional, by default generated using app id.
*/
readonly upgradeCode?: string | null

/**
* If `warningsAsErrors` is `true` (default): treat warnings as errors. If `warningsAsErrors` is `false`: allow warnings.
* @default true
*/
readonly warningsAsErrors?: boolean
}
55 changes: 2 additions & 53 deletions packages/electron-builder/src/options/winOptions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PlatformSpecificBuildOptions, TargetConfigType, TargetSpecificOptions } from "../index"
import { PlatformSpecificBuildOptions, TargetConfigType } from "../index"
import { CustomWindowsSign } from "../windowsCodeSign"

export interface WindowsConfiguration extends PlatformSpecificBuildOptions {
Expand Down Expand Up @@ -89,55 +89,4 @@ export interface WindowsConfiguration extends PlatformSpecificBuildOptions {
readonly requestedExecutionLevel?: RequestedExecutionLevel | null
}

export type RequestedExecutionLevel = "asInvoker" | "highestAvailable" | "requireAdministrator"

export interface AppXOptions extends TargetSpecificOptions {
/**
* The application id. Defaults to `identityName`. Can’t start with numbers.
*/
readonly applicationId?: string

/**
* The background color of the app tile. See [Visual Elements](https://msdn.microsoft.com/en-us/library/windows/apps/br211471.aspx).
* @default #464646
*/
readonly backgroundColor?: string | null

/**
* A friendly name that can be displayed to users. Corresponds to [Properties.DisplayName](https://msdn.microsoft.com/en-us/library/windows/apps/br211432.aspx).
* Defaults to the application product name.
*/
readonly displayName?: string | null

/**
* The name. Corresponds to [Identity.Name](https://msdn.microsoft.com/en-us/library/windows/apps/br211441.aspx). Defaults to the [application name](/configuration/configuration#Metadata-name).
*/
readonly identityName?: string | null

/**
* The Windows Store publisher. Not used if AppX is build for testing. See [AppX Package Code Signing](#appx-package-code-signing) below.
*/
readonly publisher?: string | null

/**
* A friendly name for the publisher that can be displayed to users. Corresponds to [Properties.PublisherDisplayName](https://msdn.microsoft.com/en-us/library/windows/apps/br211460.aspx).
* Defaults to company name from the application metadata.
*/
readonly publisherDisplayName?: string | null

/**
* The list of [supported languages](https://docs.microsoft.com/en-us/windows/uwp/globalizing/manage-language-and-region#specify-the-supported-languages-in-the-apps-manifest) that will be listed in the Windows Store.
* The first entry (index 0) will be the default language.
* Defaults to en-US if omitted.
*/
readonly languages?: Array<string> | string | null

/**
* @private
* @default false
*/
readonly electronUpdaterAware?: boolean

/** @private */
readonly makeappxArgs?: Array<string> | null
}
export type RequestedExecutionLevel = "asInvoker" | "highestAvailable" | "requireAdministrator"
Loading

0 comments on commit 9596448

Please sign in to comment.