mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-09-14 19:32:10 +02:00
Compare commits
34 Commits
Author | SHA1 | Date | |
---|---|---|---|
b6b26142f8 | |||
4ee99376fd | |||
b0261342ff | |||
87fd2a521e | |||
334793c6f6 | |||
3e70d991bb | |||
feec96fc5c | |||
765984709e | |||
c7c9931f68 | |||
ae64573510 | |||
d675af5aa4 | |||
9480d17cfc | |||
5ac1df2283 | |||
20119db883 | |||
a4006deb8c | |||
25fa3cefab | |||
bb5161eb34 | |||
1bfc403a98 | |||
720d10e543 | |||
30c117672e | |||
6d1b5c77d1 | |||
d1cbf608e0 | |||
7e3014c52d | |||
82beb1f5a7 | |||
657dc81300 | |||
8e22192dd3 | |||
dc0b7d58e3 | |||
6919e5bdb0 | |||
9728a62efa | |||
276e070759 | |||
fadea54f8d | |||
523d340ade | |||
96fa7efb66 | |||
03591f8317 |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -17,9 +17,13 @@
|
|||||||
[Rr]eleases/
|
[Rr]eleases/
|
||||||
x64/
|
x64/
|
||||||
x86/
|
x86/
|
||||||
bld/
|
|
||||||
[Bb]in/
|
[Bb]in/
|
||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
|
bld/*
|
||||||
|
!bld/gen_full.iss
|
||||||
|
!bld/gen_port.iss
|
||||||
|
!bld/gen_upd.iss
|
||||||
|
!bld/Resources
|
||||||
|
|
||||||
# Visual Studio 2015 cache/options directory
|
# Visual Studio 2015 cache/options directory
|
||||||
.vs/
|
.vs/
|
||||||
|
@@ -58,7 +58,7 @@ namespace TweetDck.Configuration{
|
|||||||
Process foundProcess = Process.GetProcessById(pid);
|
Process foundProcess = Process.GetProcessById(pid);
|
||||||
|
|
||||||
using(Process currentProcess = Process.GetCurrentProcess()){
|
using(Process currentProcess = Process.GetCurrentProcess()){
|
||||||
if (foundProcess.ProcessName == currentProcess.ProcessName){
|
if (foundProcess.ProcessName == currentProcess.ProcessName || foundProcess.MainWindowTitle == Program.BrandName){
|
||||||
LockingProcess = foundProcess;
|
LockingProcess = foundProcess;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using TweetDck.Core.Utils;
|
||||||
|
|
||||||
namespace TweetDck.Core.Controls{
|
namespace TweetDck.Core.Controls{
|
||||||
static class ControlExtensions{
|
static class ControlExtensions{
|
||||||
@@ -35,6 +36,12 @@ namespace TweetDck.Core.Controls{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void SetElevated(this Button button){
|
||||||
|
button.Text = " "+button.Text;
|
||||||
|
button.FlatStyle = FlatStyle.System;
|
||||||
|
NativeMethods.SendMessage(button.Handle, NativeMethods.BCM_SETSHIELD, 0, new IntPtr(1));
|
||||||
|
}
|
||||||
|
|
||||||
public static void EnableMultilineShortcuts(this TextBox textBox){
|
public static void EnableMultilineShortcuts(this TextBox textBox){
|
||||||
textBox.KeyDown += (sender, args) => {
|
textBox.KeyDown += (sender, args) => {
|
||||||
if (args.Control && args.KeyCode == Keys.A){
|
if (args.Control && args.KeyCode == Keys.A){
|
||||||
|
@@ -62,6 +62,7 @@ namespace TweetDck.Core{
|
|||||||
public bool FreezeTimer { get; set; }
|
public bool FreezeTimer { get; set; }
|
||||||
public bool ContextMenuOpen { get; set; }
|
public bool ContextMenuOpen { get; set; }
|
||||||
public string CurrentUrl { get; private set; }
|
public string CurrentUrl { get; private set; }
|
||||||
|
public string CurrentQuotedTweetUrl { get; set; }
|
||||||
|
|
||||||
public EventHandler Initialized;
|
public EventHandler Initialized;
|
||||||
private bool isInitialized;
|
private bool isInitialized;
|
||||||
@@ -225,7 +226,7 @@ namespace TweetDck.Core{
|
|||||||
tweetQueue.Enqueue(notification);
|
tweetQueue.Enqueue(notification);
|
||||||
UpdateTitle();
|
UpdateTitle();
|
||||||
|
|
||||||
if (!timerProgress.Enabled){
|
if (totalTime == 0){
|
||||||
LoadNextNotification();
|
LoadNextNotification();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -248,6 +249,7 @@ namespace TweetDck.Core{
|
|||||||
Location = new Point(-32000, -32000);
|
Location = new Point(-32000, -32000);
|
||||||
progressBarTimer.Value = Program.UserConfig.NotificationTimerCountDown ? 1000 : 0;
|
progressBarTimer.Value = Program.UserConfig.NotificationTimerCountDown ? 1000 : 0;
|
||||||
timerProgress.Stop();
|
timerProgress.Stop();
|
||||||
|
totalTime = 0;
|
||||||
|
|
||||||
StopMouseHook();
|
StopMouseHook();
|
||||||
}
|
}
|
||||||
@@ -276,6 +278,7 @@ namespace TweetDck.Core{
|
|||||||
|
|
||||||
private void LoadTweet(TweetNotification tweet){
|
private void LoadTweet(TweetNotification tweet){
|
||||||
CurrentUrl = tweet.Url;
|
CurrentUrl = tweet.Url;
|
||||||
|
CurrentQuotedTweetUrl = string.Empty; // load from JS
|
||||||
|
|
||||||
timerProgress.Stop();
|
timerProgress.Stop();
|
||||||
totalTime = timeLeft = tweet.GetDisplayDuration(Program.UserConfig.NotificationDurationValue);
|
totalTime = timeLeft = tweet.GetDisplayDuration(Program.UserConfig.NotificationDurationValue);
|
||||||
|
@@ -18,6 +18,9 @@ namespace TweetDck.Core.Handling{
|
|||||||
|
|
||||||
private readonly FormBrowser form;
|
private readonly FormBrowser form;
|
||||||
|
|
||||||
|
private string lastHighlightedTweet;
|
||||||
|
private string lastHighlightedQuotedTweet;
|
||||||
|
|
||||||
public ContextMenuBrowser(FormBrowser form){
|
public ContextMenuBrowser(FormBrowser form){
|
||||||
this.form = form;
|
this.form = form;
|
||||||
}
|
}
|
||||||
@@ -31,11 +34,14 @@ namespace TweetDck.Core.Handling{
|
|||||||
|
|
||||||
base.OnBeforeContextMenu(browserControl, browser, frame, parameters, model);
|
base.OnBeforeContextMenu(browserControl, browser, frame, parameters, model);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(TweetDeckBridge.LastHighlightedTweet) && (parameters.TypeFlags & (ContextMenuType.Editable | ContextMenuType.Selection)) == 0){
|
lastHighlightedTweet = TweetDeckBridge.LastHighlightedTweet;
|
||||||
|
lastHighlightedQuotedTweet = TweetDeckBridge.LastHighlightedQuotedTweet;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(lastHighlightedTweet) && (parameters.TypeFlags & (ContextMenuType.Editable | ContextMenuType.Selection)) == 0){
|
||||||
model.AddItem((CefMenuCommand)MenuOpenTweetUrl, "Open tweet in browser");
|
model.AddItem((CefMenuCommand)MenuOpenTweetUrl, "Open tweet in browser");
|
||||||
model.AddItem((CefMenuCommand)MenuCopyTweetUrl, "Copy tweet address");
|
model.AddItem((CefMenuCommand)MenuCopyTweetUrl, "Copy tweet address");
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(TweetDeckBridge.LastHighlightedQuotedTweet)){
|
if (!string.IsNullOrEmpty(lastHighlightedQuotedTweet)){
|
||||||
model.AddSeparator();
|
model.AddSeparator();
|
||||||
model.AddItem((CefMenuCommand)MenuOpenQuotedTweetUrl, "Open quoted tweet in browser");
|
model.AddItem((CefMenuCommand)MenuOpenQuotedTweetUrl, "Open quoted tweet in browser");
|
||||||
model.AddItem((CefMenuCommand)MenuCopyQuotedTweetUrl, "Copy quoted tweet address");
|
model.AddItem((CefMenuCommand)MenuCopyQuotedTweetUrl, "Copy quoted tweet address");
|
||||||
@@ -91,19 +97,19 @@ namespace TweetDck.Core.Handling{
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case MenuOpenTweetUrl:
|
case MenuOpenTweetUrl:
|
||||||
BrowserUtils.OpenExternalBrowser(TweetDeckBridge.LastHighlightedTweet);
|
BrowserUtils.OpenExternalBrowser(lastHighlightedTweet);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case MenuCopyTweetUrl:
|
case MenuCopyTweetUrl:
|
||||||
Clipboard.SetText(TweetDeckBridge.LastHighlightedTweet, TextDataFormat.UnicodeText);
|
Clipboard.SetText(lastHighlightedTweet, TextDataFormat.UnicodeText);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case MenuOpenQuotedTweetUrl:
|
case MenuOpenQuotedTweetUrl:
|
||||||
BrowserUtils.OpenExternalBrowser(TweetDeckBridge.LastHighlightedQuotedTweet);
|
BrowserUtils.OpenExternalBrowser(lastHighlightedQuotedTweet);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case MenuCopyQuotedTweetUrl:
|
case MenuCopyQuotedTweetUrl:
|
||||||
Clipboard.SetText(TweetDeckBridge.LastHighlightedQuotedTweet, TextDataFormat.UnicodeText);
|
Clipboard.SetText(lastHighlightedQuotedTweet, TextDataFormat.UnicodeText);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,7 +7,7 @@ namespace TweetDck.Core.Handling{
|
|||||||
private const int MenuSkipTweet = 26600;
|
private const int MenuSkipTweet = 26600;
|
||||||
private const int MenuFreeze = 26601;
|
private const int MenuFreeze = 26601;
|
||||||
private const int MenuCopyTweetUrl = 26602;
|
private const int MenuCopyTweetUrl = 26602;
|
||||||
private const int MenuCopyTweetEmbeddedUrl = 26603;
|
private const int MenuCopyQuotedTweetUrl = 26603;
|
||||||
|
|
||||||
private readonly FormNotification form;
|
private readonly FormNotification form;
|
||||||
private readonly bool enableCustomMenu;
|
private readonly bool enableCustomMenu;
|
||||||
@@ -29,8 +29,8 @@ namespace TweetDck.Core.Handling{
|
|||||||
if (!string.IsNullOrEmpty(form.CurrentUrl)){
|
if (!string.IsNullOrEmpty(form.CurrentUrl)){
|
||||||
model.AddItem((CefMenuCommand)MenuCopyTweetUrl, "Copy tweet address");
|
model.AddItem((CefMenuCommand)MenuCopyTweetUrl, "Copy tweet address");
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(TweetDeckBridge.NotificationTweetEmbedded)){
|
if (!string.IsNullOrEmpty(form.CurrentQuotedTweetUrl)){
|
||||||
model.AddItem((CefMenuCommand)MenuCopyTweetEmbeddedUrl, "Copy quoted tweet address");
|
model.AddItem((CefMenuCommand)MenuCopyQuotedTweetUrl, "Copy quoted tweet address");
|
||||||
}
|
}
|
||||||
|
|
||||||
model.AddSeparator();
|
model.AddSeparator();
|
||||||
@@ -61,8 +61,8 @@ namespace TweetDck.Core.Handling{
|
|||||||
Clipboard.SetText(form.CurrentUrl, TextDataFormat.UnicodeText);
|
Clipboard.SetText(form.CurrentUrl, TextDataFormat.UnicodeText);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case MenuCopyTweetEmbeddedUrl:
|
case MenuCopyQuotedTweetUrl:
|
||||||
Clipboard.SetText(TweetDeckBridge.NotificationTweetEmbedded, TextDataFormat.UnicodeText);
|
Clipboard.SetText(form.CurrentQuotedTweetUrl, TextDataFormat.UnicodeText);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11,7 +11,6 @@ namespace TweetDck.Core.Handling{
|
|||||||
public static string LastRightClickedLink = string.Empty;
|
public static string LastRightClickedLink = string.Empty;
|
||||||
public static string LastHighlightedTweet = string.Empty;
|
public static string LastHighlightedTweet = string.Empty;
|
||||||
public static string LastHighlightedQuotedTweet = string.Empty;
|
public static string LastHighlightedQuotedTweet = string.Empty;
|
||||||
public static string NotificationTweetEmbedded = string.Empty;
|
|
||||||
public static string ClipboardImagePath = string.Empty;
|
public static string ClipboardImagePath = string.Empty;
|
||||||
|
|
||||||
private readonly FormBrowser form;
|
private readonly FormBrowser form;
|
||||||
@@ -81,8 +80,8 @@ namespace TweetDck.Core.Handling{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetNotificationTweetEmbedded(string link){
|
public void SetNotificationQuotedTweet(string link){
|
||||||
form.InvokeSafe(() => NotificationTweetEmbedded = link);
|
notification.InvokeSafe(() => notification.CurrentQuotedTweetUrl = link);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OpenSettingsMenu(){
|
public void OpenSettingsMenu(){
|
||||||
|
64
Core/Other/Settings/TabSettingsAdvanced.Designer.cs
generated
64
Core/Other/Settings/TabSettingsAdvanced.Designer.cs
generated
@@ -29,14 +29,15 @@
|
|||||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||||
this.btnEditCefArgs = new System.Windows.Forms.Button();
|
this.btnEditCefArgs = new System.Windows.Forms.Button();
|
||||||
this.btnEditCSS = new System.Windows.Forms.Button();
|
this.btnEditCSS = new System.Windows.Forms.Button();
|
||||||
|
this.btnRestartLog = new System.Windows.Forms.Button();
|
||||||
|
this.btnRestart = new System.Windows.Forms.Button();
|
||||||
this.btnReset = new System.Windows.Forms.Button();
|
this.btnReset = new System.Windows.Forms.Button();
|
||||||
this.btnImport = new System.Windows.Forms.Button();
|
this.btnImport = new System.Windows.Forms.Button();
|
||||||
this.btnExport = new System.Windows.Forms.Button();
|
this.btnExport = new System.Windows.Forms.Button();
|
||||||
this.groupPerformance = new System.Windows.Forms.GroupBox();
|
this.groupPerformance = new System.Windows.Forms.GroupBox();
|
||||||
this.groupConfiguration = new System.Windows.Forms.GroupBox();
|
this.groupConfiguration = new System.Windows.Forms.GroupBox();
|
||||||
this.groupApp = new System.Windows.Forms.GroupBox();
|
this.groupApp = new System.Windows.Forms.GroupBox();
|
||||||
this.btnRestartLog = new System.Windows.Forms.Button();
|
this.btnOpenAppFolder = new System.Windows.Forms.Button();
|
||||||
this.btnRestart = new System.Windows.Forms.Button();
|
|
||||||
this.groupPerformance.SuspendLayout();
|
this.groupPerformance.SuspendLayout();
|
||||||
this.groupConfiguration.SuspendLayout();
|
this.groupConfiguration.SuspendLayout();
|
||||||
this.groupApp.SuspendLayout();
|
this.groupApp.SuspendLayout();
|
||||||
@@ -90,6 +91,30 @@
|
|||||||
this.btnEditCSS.UseVisualStyleBackColor = true;
|
this.btnEditCSS.UseVisualStyleBackColor = true;
|
||||||
this.btnEditCSS.Click += new System.EventHandler(this.btnEditCSS_Click);
|
this.btnEditCSS.Click += new System.EventHandler(this.btnEditCSS_Click);
|
||||||
//
|
//
|
||||||
|
// btnRestartLog
|
||||||
|
//
|
||||||
|
this.btnRestartLog.Location = new System.Drawing.Point(6, 77);
|
||||||
|
this.btnRestartLog.Name = "btnRestartLog";
|
||||||
|
this.btnRestartLog.Size = new System.Drawing.Size(171, 23);
|
||||||
|
this.btnRestartLog.TabIndex = 18;
|
||||||
|
this.btnRestartLog.Text = "Restart with Logging";
|
||||||
|
this.toolTip.SetToolTip(this.btnRestartLog, "Restarts the program and enables logging\r\ninto a debug.txt file in the installati" +
|
||||||
|
"on folder.");
|
||||||
|
this.btnRestartLog.UseVisualStyleBackColor = true;
|
||||||
|
this.btnRestartLog.Click += new System.EventHandler(this.btnRestartLog_Click);
|
||||||
|
//
|
||||||
|
// btnRestart
|
||||||
|
//
|
||||||
|
this.btnRestart.Location = new System.Drawing.Point(6, 48);
|
||||||
|
this.btnRestart.Name = "btnRestart";
|
||||||
|
this.btnRestart.Size = new System.Drawing.Size(171, 23);
|
||||||
|
this.btnRestart.TabIndex = 17;
|
||||||
|
this.btnRestart.Text = "Restart the Program";
|
||||||
|
this.toolTip.SetToolTip(this.btnRestart, "Restarts the program using the same command\r\nline arguments that were used at lau" +
|
||||||
|
"nch.");
|
||||||
|
this.btnRestart.UseVisualStyleBackColor = true;
|
||||||
|
this.btnRestart.Click += new System.EventHandler(this.btnRestart_Click);
|
||||||
|
//
|
||||||
// btnReset
|
// btnReset
|
||||||
//
|
//
|
||||||
this.btnReset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
this.btnReset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||||
@@ -154,38 +179,26 @@
|
|||||||
//
|
//
|
||||||
// groupApp
|
// groupApp
|
||||||
//
|
//
|
||||||
|
this.groupApp.Controls.Add(this.btnOpenAppFolder);
|
||||||
this.groupApp.Controls.Add(this.btnRestartLog);
|
this.groupApp.Controls.Add(this.btnRestartLog);
|
||||||
this.groupApp.Controls.Add(this.btnRestart);
|
this.groupApp.Controls.Add(this.btnRestart);
|
||||||
this.groupApp.Location = new System.Drawing.Point(198, 9);
|
this.groupApp.Location = new System.Drawing.Point(198, 9);
|
||||||
this.groupApp.Name = "groupApp";
|
this.groupApp.Name = "groupApp";
|
||||||
this.groupApp.Size = new System.Drawing.Size(183, 77);
|
this.groupApp.Size = new System.Drawing.Size(183, 106);
|
||||||
this.groupApp.TabIndex = 20;
|
this.groupApp.TabIndex = 20;
|
||||||
this.groupApp.TabStop = false;
|
this.groupApp.TabStop = false;
|
||||||
this.groupApp.Text = "App";
|
this.groupApp.Text = "App";
|
||||||
//
|
//
|
||||||
// btnRestartLog
|
// btnOpenAppFolder
|
||||||
//
|
//
|
||||||
this.btnRestartLog.Location = new System.Drawing.Point(6, 48);
|
this.btnOpenAppFolder.Location = new System.Drawing.Point(6, 19);
|
||||||
this.btnRestartLog.Name = "btnRestartLog";
|
this.btnOpenAppFolder.Name = "btnOpenAppFolder";
|
||||||
this.btnRestartLog.Size = new System.Drawing.Size(171, 23);
|
this.btnOpenAppFolder.Size = new System.Drawing.Size(171, 23);
|
||||||
this.btnRestartLog.TabIndex = 17;
|
this.btnOpenAppFolder.TabIndex = 16;
|
||||||
this.btnRestartLog.Text = "Restart with Logging";
|
this.btnOpenAppFolder.Text = "Open Program Folder";
|
||||||
this.toolTip.SetToolTip(this.btnRestartLog, "Restarts the program and enables logging\r\ninto a debug.txt file in the installati" +
|
this.toolTip.SetToolTip(this.btnOpenAppFolder, "Opens the folder where the app is located.");
|
||||||
"on folder.");
|
this.btnOpenAppFolder.UseVisualStyleBackColor = true;
|
||||||
this.btnRestartLog.UseVisualStyleBackColor = true;
|
this.btnOpenAppFolder.Click += new System.EventHandler(this.btnOpenAppFolder_Click);
|
||||||
this.btnRestartLog.Click += new System.EventHandler(this.btnRestartLog_Click);
|
|
||||||
//
|
|
||||||
// btnRestart
|
|
||||||
//
|
|
||||||
this.btnRestart.Location = new System.Drawing.Point(6, 19);
|
|
||||||
this.btnRestart.Name = "btnRestart";
|
|
||||||
this.btnRestart.Size = new System.Drawing.Size(171, 23);
|
|
||||||
this.btnRestart.TabIndex = 16;
|
|
||||||
this.btnRestart.Text = "Restart the Program";
|
|
||||||
this.toolTip.SetToolTip(this.btnRestart, "Restarts the program using the same command\r\nline arguments that were used at lau" +
|
|
||||||
"nch.");
|
|
||||||
this.btnRestart.UseVisualStyleBackColor = true;
|
|
||||||
this.btnRestart.Click += new System.EventHandler(this.btnRestart_Click);
|
|
||||||
//
|
//
|
||||||
// TabSettingsAdvanced
|
// TabSettingsAdvanced
|
||||||
//
|
//
|
||||||
@@ -223,5 +236,6 @@
|
|||||||
private System.Windows.Forms.GroupBox groupApp;
|
private System.Windows.Forms.GroupBox groupApp;
|
||||||
private System.Windows.Forms.Button btnRestartLog;
|
private System.Windows.Forms.Button btnRestartLog;
|
||||||
private System.Windows.Forms.Button btnRestart;
|
private System.Windows.Forms.Button btnRestart;
|
||||||
|
private System.Windows.Forms.Button btnOpenAppFolder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using TweetDck.Core.Controls;
|
using TweetDck.Core.Controls;
|
||||||
using TweetDck.Core.Other.Settings.Dialogs;
|
using TweetDck.Core.Other.Settings.Dialogs;
|
||||||
@@ -156,6 +157,10 @@ namespace TweetDck.Core.Other.Settings{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void btnOpenAppFolder_Click(object sender, EventArgs e){
|
||||||
|
using(Process.Start("explorer.exe", "\""+Program.ProgramPath+"\"")){}
|
||||||
|
}
|
||||||
|
|
||||||
private void btnRestart_Click(object sender, EventArgs e){
|
private void btnRestart_Click(object sender, EventArgs e){
|
||||||
Program.Restart();
|
Program.Restart();
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,7 @@ namespace TweetDck.Core.Utils{
|
|||||||
public const int MOUSEEVENTF_RIGHTUP = 0x10;
|
public const int MOUSEEVENTF_RIGHTUP = 0x10;
|
||||||
|
|
||||||
public const int SB_HORZ = 0;
|
public const int SB_HORZ = 0;
|
||||||
|
public const int BCM_SETSHIELD = 0x160C;
|
||||||
|
|
||||||
public const int WH_MOUSE_LL = 14;
|
public const int WH_MOUSE_LL = 14;
|
||||||
public const int WH_MOUSEWHEEL = 0x020A;
|
public const int WH_MOUSEWHEEL = 0x020A;
|
||||||
|
@@ -8,6 +8,7 @@ using System.Windows.Forms;
|
|||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using TweetDck.Core.Other;
|
using TweetDck.Core.Other;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using TweetDck.Core.Controls;
|
||||||
|
|
||||||
namespace TweetDck.Migration{
|
namespace TweetDck.Migration{
|
||||||
static class MigrationManager{
|
static class MigrationManager{
|
||||||
@@ -41,8 +42,9 @@ namespace TweetDck.Migration{
|
|||||||
Button btnMigrate = formQuestion.AddButton("Migrate");
|
Button btnMigrate = formQuestion.AddButton("Migrate");
|
||||||
Button btnMigrateAndPurge = formQuestion.AddButton("Migrate && Purge");
|
Button btnMigrateAndPurge = formQuestion.AddButton("Migrate && Purge");
|
||||||
|
|
||||||
btnMigrateAndPurge.Location = new Point(btnMigrateAndPurge.Location.X-18, btnMigrateAndPurge.Location.Y);
|
btnMigrateAndPurge.Location = new Point(btnMigrateAndPurge.Location.X-20, btnMigrateAndPurge.Location.Y);
|
||||||
btnMigrateAndPurge.Width += 18;
|
btnMigrateAndPurge.Width += 20;
|
||||||
|
btnMigrateAndPurge.SetElevated();
|
||||||
|
|
||||||
if (formQuestion.ShowDialog() == DialogResult.OK){
|
if (formQuestion.ShowDialog() == DialogResult.OK){
|
||||||
decision = formQuestion.ClickedButton == btnMigrateAndPurge ? MigrationDecision.MigratePurge :
|
decision = formQuestion.ClickedButton == btnMigrateAndPurge ? MigrationDecision.MigratePurge :
|
||||||
@@ -86,10 +88,20 @@ namespace TweetDck.Migration{
|
|||||||
else if (!Program.UserConfig.IgnoreUninstallCheck){
|
else if (!Program.UserConfig.IgnoreUninstallCheck){
|
||||||
string guid = MigrationUtils.FindProgramGuidByDisplayName("TweetDeck");
|
string guid = MigrationUtils.FindProgramGuidByDisplayName("TweetDeck");
|
||||||
|
|
||||||
if (guid != null && MessageBox.Show("TweetDeck is still installed on your computer, do you want to uninstall it?", "Uninstall TweetDeck", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes){
|
if (guid != null){
|
||||||
MigrationUtils.RunUninstaller(guid, 0);
|
const string prompt = "TweetDeck is still installed on your computer, do you want to uninstall it?";
|
||||||
|
|
||||||
|
using(FormMessage formQuestion = new FormMessage("Uninstall TweetDeck", prompt, MessageBoxIcon.Question)){
|
||||||
|
formQuestion.AddButton("No");
|
||||||
|
|
||||||
|
Button btnYes = formQuestion.AddButton("Yes");
|
||||||
|
btnYes.SetElevated();
|
||||||
|
|
||||||
|
if (formQuestion.ShowDialog() == DialogResult.OK && formQuestion.ClickedButton == btnYes && MigrationUtils.RunUninstaller(guid, 0)){
|
||||||
CleanupTweetDeck();
|
CleanupTweetDeck();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Program.UserConfig.IgnoreUninstallCheck = true;
|
Program.UserConfig.IgnoreUninstallCheck = true;
|
||||||
Program.UserConfig.Save();
|
Program.UserConfig.Save();
|
||||||
@@ -155,8 +167,8 @@ namespace TweetDck.Migration{
|
|||||||
// uninstall in the background
|
// uninstall in the background
|
||||||
string guid = MigrationUtils.FindProgramGuidByDisplayName("TweetDeck");
|
string guid = MigrationUtils.FindProgramGuidByDisplayName("TweetDeck");
|
||||||
|
|
||||||
if (guid != null){
|
if (guid != null && !MigrationUtils.RunUninstaller(guid, 5000)){
|
||||||
MigrationUtils.RunUninstaller(guid, 5000);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// registry cleanup
|
// registry cleanup
|
||||||
|
@@ -5,8 +5,13 @@ using Microsoft.Win32;
|
|||||||
|
|
||||||
namespace TweetDck.Migration{
|
namespace TweetDck.Migration{
|
||||||
static class MigrationUtils{
|
static class MigrationUtils{
|
||||||
public static void RunUninstaller(string guid, int timeout){
|
public static bool RunUninstaller(string guid, int timeout){
|
||||||
Process uninstaller = Process.Start("msiexec.exe", "/x "+guid+" /quiet /qn");
|
try{
|
||||||
|
Process uninstaller = Process.Start(new ProcessStartInfo{
|
||||||
|
FileName = "msiexec.exe",
|
||||||
|
Arguments = "/x "+guid+" /quiet /qn",
|
||||||
|
Verb = "runas"
|
||||||
|
});
|
||||||
|
|
||||||
if (uninstaller != null){
|
if (uninstaller != null){
|
||||||
if (timeout > 0){
|
if (timeout > 0){
|
||||||
@@ -15,6 +20,11 @@ namespace TweetDck.Migration{
|
|||||||
|
|
||||||
uninstaller.Close();
|
uninstaller.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}catch(Exception){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string FindProgramGuidByDisplayName(string displayName){
|
public static string FindProgramGuidByDisplayName(string displayName){
|
||||||
|
12
Program.cs
12
Program.cs
@@ -23,8 +23,8 @@ namespace TweetDck{
|
|||||||
|
|
||||||
public const string BrowserSubprocess = BrandName+".Browser.exe";
|
public const string BrowserSubprocess = BrandName+".Browser.exe";
|
||||||
|
|
||||||
public const string VersionTag = "1.4";
|
public const string VersionTag = "1.4.3";
|
||||||
public const string VersionFull = "1.4.0.0";
|
public const string VersionFull = "1.4.3.0";
|
||||||
|
|
||||||
public static readonly Version Version = new Version(VersionTag);
|
public static readonly Version Version = new Version(VersionTag);
|
||||||
|
|
||||||
@@ -120,6 +120,7 @@ namespace TweetDck{
|
|||||||
Locale = Args.GetValue("-locale", "en"),
|
Locale = Args.GetValue("-locale", "en"),
|
||||||
CachePath = StoragePath,
|
CachePath = StoragePath,
|
||||||
BrowserSubprocessPath = File.Exists(BrowserSubprocess) ? BrowserSubprocess : "CefSharp.BrowserSubprocess.exe",
|
BrowserSubprocessPath = File.Exists(BrowserSubprocess) ? BrowserSubprocess : "CefSharp.BrowserSubprocess.exe",
|
||||||
|
LogFile = Path.Combine(StoragePath, "TD_Console.txt"),
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
LogSeverity = Args.HasFlag("-log") ? LogSeverity.Info : LogSeverity.Disable
|
LogSeverity = Args.HasFlag("-log") ? LogSeverity.Info : LogSeverity.Disable
|
||||||
#endif
|
#endif
|
||||||
@@ -127,6 +128,11 @@ namespace TweetDck{
|
|||||||
|
|
||||||
CommandLineArgsParser.ReadCefArguments(UserConfig.CustomCefArgs).ToDictionary(settings.CefCommandLineArgs);
|
CommandLineArgsParser.ReadCefArguments(UserConfig.CustomCefArgs).ToDictionary(settings.CefCommandLineArgs);
|
||||||
|
|
||||||
|
if (!HardwareAcceleration.IsEnabled){
|
||||||
|
settings.CefCommandLineArgs["disable-gpu"] = "1";
|
||||||
|
settings.CefCommandLineArgs["disable-gpu-vsync"] = "1";
|
||||||
|
}
|
||||||
|
|
||||||
Cef.Initialize(settings, false, new BrowserProcessHandler());
|
Cef.Initialize(settings, false, new BrowserProcessHandler());
|
||||||
|
|
||||||
Application.ApplicationExit += (sender, args) => ExitCleanup();
|
Application.ApplicationExit += (sender, args) => ExitCleanup();
|
||||||
@@ -142,7 +148,7 @@ namespace TweetDck{
|
|||||||
if (mainForm.UpdateInstallerPath != null){
|
if (mainForm.UpdateInstallerPath != null){
|
||||||
ExitCleanup();
|
ExitCleanup();
|
||||||
|
|
||||||
Process.Start(mainForm.UpdateInstallerPath, "/SP- /SILENT /NOICONS /CLOSEAPPLICATIONS");
|
Process.Start(mainForm.UpdateInstallerPath, "/SP- /SILENT /CLOSEAPPLICATIONS /UPDATEPATH=\""+ProgramPath+"\""+(IsPortable ? " /PORTABLE=1" : "")); // ProgramPath has a trailing backslash
|
||||||
Application.Exit();
|
Application.Exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,7 @@ enabled(){
|
|||||||
this.lastSelectedAccount = null;
|
this.lastSelectedAccount = null;
|
||||||
|
|
||||||
this.uiComposeTweetEvent = (e, data) => {
|
this.uiComposeTweetEvent = (e, data) => {
|
||||||
if (data.type !== "reply"){
|
if (data.type !== "reply" || data.popFromInline || !("element" in data)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,15 +6,11 @@ constructor(){
|
|||||||
|
|
||||||
enabled(){
|
enabled(){
|
||||||
// add a stylesheet
|
// add a stylesheet
|
||||||
this.css = window.TDPF_createCustomStyle(this);
|
window.TDPF_createCustomStyle(this).insert(".column-detail .timeline-poll-container { display: none }");
|
||||||
this.css.insert(".column-detail .timeline-poll-container { display: none }");
|
|
||||||
|
|
||||||
// setup layout injecting
|
// setup layout injecting
|
||||||
this.prevMustaches = {};
|
|
||||||
|
|
||||||
var injectLayout = (mustache, onlyIfNotFound, search, replace) => {
|
var injectLayout = (mustache, onlyIfNotFound, search, replace) => {
|
||||||
if (TD.mustaches[mustache].indexOf(onlyIfNotFound) === -1){
|
if (TD.mustaches[mustache].indexOf(onlyIfNotFound) === -1){
|
||||||
this.prevMustaches[mustache] = TD.mustaches[mustache];
|
|
||||||
TD.mustaches[mustache] = TD.mustaches[mustache].replace(search, replace);
|
TD.mustaches[mustache] = TD.mustaches[mustache].replace(search, replace);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -25,6 +21,5 @@ enabled(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
disabled(){
|
disabled(){
|
||||||
this.css.remove();
|
// not needed, plugin reloads the page when enabled or disabled
|
||||||
Object.keys(this.prevMustaches).forEach(mustache => TD.mustaches[mustache] = this.prevMustaches[mustache]);
|
|
||||||
}
|
}
|
@@ -104,11 +104,14 @@
|
|||||||
var html = $(tweet.render({
|
var html = $(tweet.render({
|
||||||
withFooter: false,
|
withFooter: false,
|
||||||
withTweetActions: false,
|
withTweetActions: false,
|
||||||
withMediaPreview: false
|
withMediaPreview: true,
|
||||||
|
isMediaPreviewOff: true,
|
||||||
|
isMediaPreviewSmall: false,
|
||||||
|
isMediaPreviewLarge: false
|
||||||
}));
|
}));
|
||||||
|
|
||||||
html.css("border", "0");
|
html.css("border", "0");
|
||||||
html.find(".tweet-body").first().children("footer").remove();
|
html.find("footer").last().remove(); // apparently withTweetActions breaks for certain tweets, nice
|
||||||
|
|
||||||
var url = html.find("time").first().children("a").first().attr("href") || "";
|
var url = html.find("time").first().children("a").first().attr("href") || "";
|
||||||
|
|
||||||
@@ -376,32 +379,39 @@
|
|||||||
//
|
//
|
||||||
// Block: Support for extra mouse buttons.
|
// Block: Support for extra mouse buttons.
|
||||||
//
|
//
|
||||||
|
(function(){
|
||||||
|
var tryClickSelector = function(selector, parent){
|
||||||
|
return $(selector, parent).click().length;
|
||||||
|
};
|
||||||
|
|
||||||
|
var tryCloseModal = function(){
|
||||||
|
var modal = $("#open-modal");
|
||||||
|
return modal.is(":visible") && tryClickSelector("a[rel=dismiss]", modal);
|
||||||
|
};
|
||||||
|
|
||||||
|
var tryCloseHighlightedColumn = function(){
|
||||||
|
if (highlightedColumnEle){
|
||||||
|
var column = highlightedColumnEle.closest(".js-column");
|
||||||
|
return (column.is(".is-shifted-2") && tryClickSelector(".js-tweet-social-proof-back", column)) || (column.is(".is-shifted-1") && tryClickSelector(".js-column-back", column));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
window.TDGF_onMouseClickExtra = function(button){
|
window.TDGF_onMouseClickExtra = function(button){
|
||||||
if (button === 1){ // back button
|
if (button === 1){ // back button
|
||||||
var inlineComposer, drawerComposer, modal;
|
tryCloseModal() ||
|
||||||
|
tryClickSelector(".js-inline-compose-close") ||
|
||||||
if ((modal = $("#open-modal")).is(":visible")){
|
tryCloseHighlightedColumn() ||
|
||||||
modal.find("a[rel=dismiss]").click();
|
tryClickSelector(".js-app-content.is-open .js-drawer-close:visible") ||
|
||||||
}
|
tryClickSelector(".is-shifted-2 .js-tweet-social-proof-back") ||
|
||||||
else if ((inlineComposer = $(".js-inline-compose-close")).length === 1){
|
|
||||||
inlineComposer.click();
|
|
||||||
}
|
|
||||||
else if (highlightedColumnEle && highlightedColumnEle.closest(".js-column").is(".is-shifted-1")){
|
|
||||||
highlightedColumnEle.find(".js-column-back").first().click();
|
|
||||||
}
|
|
||||||
else if ((drawerComposer = $(".js-app-content.is-open .js-drawer-close:visible")).length === 1){
|
|
||||||
drawerComposer.click();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$(".js-column-back").click();
|
$(".js-column-back").click();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (button === 2){ // forward button
|
else if (button === 2){ // forward button
|
||||||
if (highlightedTweetEle){
|
if (highlightedTweetEle){
|
||||||
highlightedTweetEle.children().first().click();
|
highlightedTweetEle.children().first().click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Block: Fix scheduled tweets not showing up sometimes.
|
// Block: Fix scheduled tweets not showing up sometimes.
|
||||||
|
@@ -114,7 +114,7 @@
|
|||||||
var account = embedded[0].getElementsByClassName("account-link");
|
var account = embedded[0].getElementsByClassName("account-link");
|
||||||
if (account.length === 0)return;
|
if (account.length === 0)return;
|
||||||
|
|
||||||
$TD.setNotificationTweetEmbedded(account[0].getAttribute("href")+"/status/"+tweetId);
|
$TD.setNotificationQuotedTweet(account[0].getAttribute("href")+"/status/"+tweetId);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@@ -19,7 +19,6 @@
|
|||||||
//
|
//
|
||||||
var createUpdateNotificationElement = function(version, download){
|
var createUpdateNotificationElement = function(version, download){
|
||||||
var outdated = version === "unsupported";
|
var outdated = version === "unsupported";
|
||||||
var tweetdick = version === "tweetdick";
|
|
||||||
|
|
||||||
var ele = $("#tweetdck-update");
|
var ele = $("#tweetdck-update");
|
||||||
var existed = ele.length > 0;
|
var existed = ele.length > 0;
|
||||||
@@ -37,15 +36,6 @@
|
|||||||
"<button class='btn btn-negative tdu-btn-dismiss'><span class='label'>Dismiss</span></button>",
|
"<button class='btn btn-negative tdu-btn-dismiss'><span class='label'>Dismiss</span></button>",
|
||||||
"</div>",
|
"</div>",
|
||||||
"</div>"
|
"</div>"
|
||||||
] : tweetdick ? [
|
|
||||||
"<div id='tweetdck-update'>",
|
|
||||||
"<p class='tdu-title'>TweetDick Ending</p>",
|
|
||||||
"<p class='tdu-info'>Please, move to TweetDuck.</p>",
|
|
||||||
"<div class='tdu-buttons'>",
|
|
||||||
"<button class='btn btn-positive tdu-btn-unsupported'><span class='label'>Read More</span></button>",
|
|
||||||
"<button class='btn btn-negative tdu-btn-dismiss'><span class='label'>Dismiss</span></button>",
|
|
||||||
"</div>",
|
|
||||||
"</div>"
|
|
||||||
] : [
|
] : [
|
||||||
"<div id='tweetdck-update'>",
|
"<div id='tweetdck-update'>",
|
||||||
"<p class='tdu-title'>"+$TDU.brandName+" Update</p>",
|
"<p class='tdu-title'>"+$TDU.brandName+" Update</p>",
|
||||||
@@ -118,10 +108,6 @@
|
|||||||
$TDU.openBrowser("https://github.com/chylex/TweetDuck/wiki/Supported-Systems");
|
$TDU.openBrowser("https://github.com/chylex/TweetDuck/wiki/Supported-Systems");
|
||||||
});
|
});
|
||||||
|
|
||||||
buttonDiv.children(".tdu-btn-tweetdick").click(function(){
|
|
||||||
$TDU.openBrowser("https://github.com/chylex/TweetDick/wiki/Future-of-TweetDick");
|
|
||||||
});
|
|
||||||
|
|
||||||
buttonDiv.children(".tdu-btn-dismiss,.tdu-btn-unsupported").click(function(){
|
buttonDiv.children(".tdu-btn-dismiss,.tdu-btn-unsupported").click(function(){
|
||||||
$TDU.onUpdateDismissed(version);
|
$TDU.onUpdateDismissed(version);
|
||||||
ele.slideUp(function(){ ele.remove(); });
|
ele.slideUp(function(){ ele.remove(); });
|
||||||
@@ -145,13 +131,6 @@
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ($TDU.brandName === "TweetDick"){
|
|
||||||
if ($TDU.dismissedVersionTag !== "tweetdick"){
|
|
||||||
createUpdateNotificationElement("tweetdick");
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
clearTimeout(updateCheckTimeoutID);
|
clearTimeout(updateCheckTimeoutID);
|
||||||
updateCheckTimeoutID = setTimeout(runUpdateCheck, 1000*60*60); // 1 hour
|
updateCheckTimeoutID = setTimeout(runUpdateCheck, 1000*60*60); // 1 hour
|
||||||
|
9
bld/Resources/LICENSE
Normal file
9
bld/Resources/LICENSE
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
BIN
bld/Resources/icon.ico
Normal file
BIN
bld/Resources/icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
161
bld/gen_full.iss
Normal file
161
bld/gen_full.iss
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
; Script generated by the Inno Script Studio Wizard.
|
||||||
|
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
||||||
|
|
||||||
|
#define MyAppName "TweetDuck"
|
||||||
|
#define MyAppPublisher "chylex"
|
||||||
|
#define MyAppURL "https://tweetduck.chylex.com"
|
||||||
|
#define MyAppExeName "TweetDuck.exe"
|
||||||
|
|
||||||
|
#define MyAppVersion GetFileVersion("..\bin\x86\Release\TweetDuck.exe")
|
||||||
|
|
||||||
|
[Setup]
|
||||||
|
AppId={{8C25A716-7E11-4AAD-9992-8B5D0C78AE06}
|
||||||
|
AppName={#MyAppName}
|
||||||
|
AppVersion={#MyAppVersion}
|
||||||
|
AppVerName={#MyAppName} {#MyAppVersion}
|
||||||
|
AppPublisher={#MyAppPublisher}
|
||||||
|
AppPublisherURL={#MyAppURL}
|
||||||
|
AppSupportURL={#MyAppURL}
|
||||||
|
AppUpdatesURL={#MyAppURL}
|
||||||
|
DefaultDirName={pf}\{#MyAppName}
|
||||||
|
DefaultGroupName={#MyAppName}
|
||||||
|
OutputBaseFilename={#MyAppName}
|
||||||
|
VersionInfoVersion={#MyAppVersion}
|
||||||
|
LicenseFile=.\Resources\LICENSE
|
||||||
|
SetupIconFile=.\Resources\icon.ico
|
||||||
|
Uninstallable=TDIsUninstallable
|
||||||
|
UninstallDisplayName={#MyAppName}
|
||||||
|
UninstallDisplayIcon={app}\{#MyAppExeName}
|
||||||
|
Compression=lzma
|
||||||
|
SolidCompression=yes
|
||||||
|
InternalCompressLevel=max
|
||||||
|
MinVersion=0,6.1
|
||||||
|
|
||||||
|
[Languages]
|
||||||
|
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||||
|
|
||||||
|
[Tasks]
|
||||||
|
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
Source: "..\bin\x86\Release\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "..\bin\x86\Release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Excludes: "*.xml,devtools_resources.pak,d3dcompiler_43.dll"
|
||||||
|
|
||||||
|
[Icons]
|
||||||
|
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Check: TDIsUninstallable
|
||||||
|
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
|
||||||
|
|
||||||
|
[Run]
|
||||||
|
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall shellexec skipifsilent
|
||||||
|
|
||||||
|
[InstallDelete]
|
||||||
|
Type: files; Name: "{app}\td-log.txt"
|
||||||
|
|
||||||
|
[UninstallDelete]
|
||||||
|
Type: files; Name: "{app}\debug.log"
|
||||||
|
Type: filesandordirs; Name: "{localappdata}\{#MyAppName}\Cache"
|
||||||
|
Type: filesandordirs; Name: "{localappdata}\{#MyAppName}\GPUCache"
|
||||||
|
|
||||||
|
[Code]
|
||||||
|
var IsPortableInstallation: Boolean;
|
||||||
|
var UpdatePath: String;
|
||||||
|
|
||||||
|
function TDGetNetFrameworkVersion: Cardinal; forward;
|
||||||
|
|
||||||
|
{ Check .NET Framework version on startup, ask user if they want to proceed if older than 4.5.2. }
|
||||||
|
function InitializeSetup: Boolean;
|
||||||
|
begin
|
||||||
|
IsPortableInstallation := ExpandConstant('{param:PORTABLEINSTALL}') = '1'
|
||||||
|
UpdatePath := ExpandConstant('{param:UPDATEPATH}')
|
||||||
|
|
||||||
|
if IsPortableInstallation and (UpdatePath = '') then
|
||||||
|
begin
|
||||||
|
MsgBox('The /PORTABLEINSTALL flag requires the /UPDATEPATH parameter.', mbCriticalError, MB_OK);
|
||||||
|
Result := False;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if TDGetNetFrameworkVersion() >= 379893 then
|
||||||
|
begin
|
||||||
|
Result := True;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (MsgBox('{#MyAppName} requires .NET Framework 4.5.2 or newer,'+#13+#10+'please download it from {#MyAppURL}'+#13+#10+#13+#10'Do you want to proceed with the setup anyway?', mbCriticalError, MB_YESNO or MB_DEFBUTTON2) = IDNO) then
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Set the installation path if updating. }
|
||||||
|
procedure InitializeWizard();
|
||||||
|
begin
|
||||||
|
if (UpdatePath <> '') then
|
||||||
|
begin
|
||||||
|
WizardForm.DirEdit.Text := UpdatePath;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Skip the install path selection page if running from an update installer. }
|
||||||
|
function ShouldSkipPage(PageID: Integer): Boolean;
|
||||||
|
begin
|
||||||
|
Result := (PageID = wpSelectDir) and (UpdatePath <> '')
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Ask user if they want to delete 'AppData\TweetDuck' and 'plugins' folders after uninstallation. }
|
||||||
|
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
|
||||||
|
var ProfileDataFolder: String;
|
||||||
|
var PluginDataFolder: String;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if CurUninstallStep = usPostUninstall then
|
||||||
|
begin
|
||||||
|
ProfileDataFolder := ExpandConstant('{localappdata}\{#MyAppName}')
|
||||||
|
PluginDataFolder := ExpandConstant('{app}\plugins')
|
||||||
|
|
||||||
|
if (DirExists(ProfileDataFolder) or DirExists(PluginDataFolder)) and (MsgBox('Do you also want to delete your {#MyAppName} profile and plugins?', mbConfirmation, MB_YESNO or MB_DEFBUTTON2) = IDYES) then
|
||||||
|
begin
|
||||||
|
DelTree(ProfileDataFolder, True, True, True);
|
||||||
|
DelTree(PluginDataFolder, True, True, True);
|
||||||
|
DelTree(ExpandConstant('{app}'), True, False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Create a 'makeportable' file if running in portable mode. }
|
||||||
|
procedure CurStepChanged(CurStep: TSetupStep);
|
||||||
|
begin
|
||||||
|
if (CurStep = ssPostInstall) and IsPortableInstallation then
|
||||||
|
begin
|
||||||
|
while not SaveStringToFile(ExpandConstant('{app}\makeportable'), '', False) do
|
||||||
|
begin
|
||||||
|
if MsgBox('Could not create a ''makeportable'' file in the installation folder. If the file is not present, the installation will not be fully portable.', mbCriticalError, MB_RETRYCANCEL) <> IDRETRY then
|
||||||
|
begin
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Returns true if the installer should create uninstallation entries (i.e. not running in portable or full update mode). }
|
||||||
|
function TDIsUninstallable: Boolean;
|
||||||
|
begin
|
||||||
|
Result := (UpdatePath = '') and not IsPortableInstallation
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Return DWORD value containing the build version of .NET Framework. }
|
||||||
|
function TDGetNetFrameworkVersion: Cardinal;
|
||||||
|
var FrameworkVersion: Cardinal;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if RegQueryDWordValue(HKEY_LOCAL_MACHINE, 'Software\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release', FrameworkVersion) then
|
||||||
|
begin
|
||||||
|
Result := FrameworkVersion;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := 0;
|
||||||
|
end;
|
150
bld/gen_port.iss
Normal file
150
bld/gen_port.iss
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
; Script generated by the Inno Script Studio Wizard.
|
||||||
|
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
||||||
|
|
||||||
|
#define MyAppName "TweetDuck"
|
||||||
|
#define MyAppPublisher "chylex"
|
||||||
|
#define MyAppURL "https://tweetduck.chylex.com"
|
||||||
|
#define MyAppExeName "TweetDuck.exe"
|
||||||
|
|
||||||
|
#define MyAppVersion GetFileVersion("..\bin\x86\Release\TweetDuck.exe")
|
||||||
|
|
||||||
|
[Setup]
|
||||||
|
AppId={{8C25A716-7E11-4AAD-9992-8B5D0C78AE06}
|
||||||
|
AppName={#MyAppName}
|
||||||
|
AppVersion={#MyAppVersion}
|
||||||
|
AppVerName={#MyAppName} {#MyAppVersion}
|
||||||
|
AppPublisher={#MyAppPublisher}
|
||||||
|
AppPublisherURL={#MyAppURL}
|
||||||
|
AppSupportURL={#MyAppURL}
|
||||||
|
AppUpdatesURL={#MyAppURL}
|
||||||
|
DefaultDirName={pf}\{#MyAppName}
|
||||||
|
DefaultGroupName={#MyAppName}
|
||||||
|
OutputBaseFilename={#MyAppName}.Portable
|
||||||
|
VersionInfoVersion={#MyAppVersion}
|
||||||
|
LicenseFile=.\Resources\LICENSE
|
||||||
|
SetupIconFile=.\Resources\icon.ico
|
||||||
|
Uninstallable=no
|
||||||
|
UsePreviousAppDir=no
|
||||||
|
Compression=lzma
|
||||||
|
SolidCompression=yes
|
||||||
|
InternalCompressLevel=max
|
||||||
|
MinVersion=0,6.1
|
||||||
|
|
||||||
|
#include <idp.iss>
|
||||||
|
|
||||||
|
[Languages]
|
||||||
|
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
Source: "..\bin\x86\Release\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
|
||||||
|
[Run]
|
||||||
|
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall shellexec
|
||||||
|
|
||||||
|
[Code]
|
||||||
|
function TDGetNetFrameworkVersion: Cardinal; forward;
|
||||||
|
function TDGetAppVersionClean: String; forward;
|
||||||
|
procedure TDExecuteFullDownload; forward;
|
||||||
|
|
||||||
|
{ Check .NET Framework version on startup, ask user if they want to proceed if older than 4.5.2, and prepare full download package. }
|
||||||
|
function InitializeSetup: Boolean;
|
||||||
|
begin
|
||||||
|
idpAddFile('https://github.com/{#MyAppPublisher}/{#MyAppName}/releases/download/'+TDGetAppVersionClean()+'/{#MyAppName}.exe', ExpandConstant('{tmp}\{#MyAppName}.Full.exe'));
|
||||||
|
|
||||||
|
if TDGetNetFrameworkVersion() >= 379893 then
|
||||||
|
begin
|
||||||
|
Result := True;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (MsgBox('{#MyAppName} requires .NET Framework 4.5.2 or newer,'+#13+#10+'please download it from {#MyAppURL}'+#13+#10+#13+#10'Do you want to proceed with the setup anyway?', mbCriticalError, MB_YESNO or MB_DEFBUTTON2) = IDNO) then
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Prepare download plugin if there are any files to download, and set the installation path. }
|
||||||
|
procedure InitializeWizard();
|
||||||
|
begin
|
||||||
|
idpDownloadAfter(wpReady);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Remove uninstallation data and application to force them to be replaced with updated ones. }
|
||||||
|
procedure CurStepChanged(CurStep: TSetupStep);
|
||||||
|
begin
|
||||||
|
if CurStep = ssInstall then
|
||||||
|
begin
|
||||||
|
TDExecuteFullDownload();
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Return DWORD value containing the build version of .NET Framework. }
|
||||||
|
function TDGetNetFrameworkVersion: Cardinal;
|
||||||
|
var FrameworkVersion: Cardinal;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if RegQueryDWordValue(HKEY_LOCAL_MACHINE, 'Software\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release', FrameworkVersion) then
|
||||||
|
begin
|
||||||
|
Result := FrameworkVersion;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Return a cleaned up form of the app version string (removes all .0 suffixes). }
|
||||||
|
function TDGetAppVersionClean: String;
|
||||||
|
var Substr: String;
|
||||||
|
var CleanVersion: String;
|
||||||
|
|
||||||
|
begin
|
||||||
|
CleanVersion := '{#MyAppVersion}'
|
||||||
|
|
||||||
|
while True do
|
||||||
|
begin
|
||||||
|
Substr := Copy(CleanVersion, Length(CleanVersion)-1, 2);
|
||||||
|
|
||||||
|
if (CompareStr(Substr, '.0') <> 0) then
|
||||||
|
begin
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
|
||||||
|
CleanVersion := Copy(CleanVersion, 1, Length(CleanVersion)-2);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := CleanVersion;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Run the full package installer if downloaded. }
|
||||||
|
procedure TDExecuteFullDownload;
|
||||||
|
var InstallFile: String;
|
||||||
|
var ResultCode: Integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
InstallFile := ExpandConstant('{tmp}\{#MyAppName}.Full.exe')
|
||||||
|
WizardForm.ProgressGauge.Style := npbstMarquee;
|
||||||
|
|
||||||
|
try
|
||||||
|
if Exec(InstallFile, '/SP- /SILENT /MERGETASKS="!desktopicon" /UPDATEPATH="'+ExpandConstant('{app}\')+'" /PORTABLEINSTALL=1', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin
|
||||||
|
if ResultCode <> 0 then
|
||||||
|
begin
|
||||||
|
DeleteFile(InstallFile);
|
||||||
|
Abort();
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
MsgBox('Could not run the full installer in portable mode. Error: '+SysErrorMessage(ResultCode), mbCriticalError, MB_OK);
|
||||||
|
|
||||||
|
DeleteFile(InstallFile);
|
||||||
|
Abort();
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
WizardForm.ProgressGauge.Style := npbstNormal;
|
||||||
|
DeleteFile(InstallFile);
|
||||||
|
end;
|
||||||
|
end;
|
264
bld/gen_upd.iss
Normal file
264
bld/gen_upd.iss
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
; Script generated by the Inno Script Studio Wizard.
|
||||||
|
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
||||||
|
|
||||||
|
#define MyAppName "TweetDuck"
|
||||||
|
#define MyAppPublisher "chylex"
|
||||||
|
#define MyAppURL "https://tweetduck.chylex.com"
|
||||||
|
#define MyAppExeName "TweetDuck.exe"
|
||||||
|
|
||||||
|
#define MyAppID "8C25A716-7E11-4AAD-9992-8B5D0C78AE06"
|
||||||
|
#define MyAppVersion GetFileVersion("..\bin\x86\Release\TweetDuck.exe")
|
||||||
|
#define CefVersion "3.2785.1478.0"
|
||||||
|
|
||||||
|
[Setup]
|
||||||
|
AppId={{{#MyAppID}}
|
||||||
|
AppName={#MyAppName}
|
||||||
|
AppVersion={#MyAppVersion}
|
||||||
|
AppVerName={#MyAppName} {#MyAppVersion}
|
||||||
|
AppPublisher={#MyAppPublisher}
|
||||||
|
AppPublisherURL={#MyAppURL}
|
||||||
|
AppSupportURL={#MyAppURL}
|
||||||
|
AppUpdatesURL={#MyAppURL}
|
||||||
|
DefaultDirName={pf}\{#MyAppName}
|
||||||
|
DefaultGroupName={#MyAppName}
|
||||||
|
OutputBaseFilename={#MyAppName}.Update
|
||||||
|
VersionInfoVersion={#MyAppVersion}
|
||||||
|
LicenseFile=.\Resources\LICENSE
|
||||||
|
SetupIconFile=.\Resources\icon.ico
|
||||||
|
Uninstallable=TDIsUninstallable
|
||||||
|
UninstallDisplayName={#MyAppName}
|
||||||
|
UninstallDisplayIcon={app}\{#MyAppExeName}
|
||||||
|
Compression=lzma
|
||||||
|
SolidCompression=yes
|
||||||
|
InternalCompressLevel=max
|
||||||
|
MinVersion=0,6.1
|
||||||
|
|
||||||
|
#include <idp.iss>
|
||||||
|
|
||||||
|
[Languages]
|
||||||
|
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
Source: "..\bin\x86\Release\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "..\bin\x86\Release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Excludes: "*.xml,*.dll,*.pak,*.bin,*.dat"
|
||||||
|
|
||||||
|
[Icons]
|
||||||
|
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
||||||
|
|
||||||
|
[Run]
|
||||||
|
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall shellexec
|
||||||
|
|
||||||
|
[InstallDelete]
|
||||||
|
Type: files; Name: "{app}\*.xml"
|
||||||
|
Type: files; Name: "{app}\*.js"
|
||||||
|
Type: files; Name: "{app}\d3dcompiler_43.dll"
|
||||||
|
Type: files; Name: "{app}\devtools_resources.pak"
|
||||||
|
Type: files; Name: "{app}\CefSharp.BrowserSubprocess.exe"
|
||||||
|
Type: files; Name: "{app}\td-log.txt"
|
||||||
|
Type: files; Name: "{app}\debug.log"
|
||||||
|
Type: files; Name: "{localappdata}\{#MyAppName}\ChromeDWriteFontCache"
|
||||||
|
|
||||||
|
[UninstallDelete]
|
||||||
|
Type: files; Name: "{app}\*.*"
|
||||||
|
Type: filesandordirs; Name: "{app}\locales"
|
||||||
|
Type: filesandordirs; Name: "{app}\scripts"
|
||||||
|
Type: filesandordirs; Name: "{localappdata}\{#MyAppName}\Cache"
|
||||||
|
Type: filesandordirs; Name: "{localappdata}\{#MyAppName}\GPUCache"
|
||||||
|
|
||||||
|
[Code]
|
||||||
|
function TDIsUninstallable: Boolean; forward;
|
||||||
|
function TDFindUpdatePath: String; forward;
|
||||||
|
function TDGetNetFrameworkVersion: Cardinal; forward;
|
||||||
|
function TDGetAppVersionClean: String; forward;
|
||||||
|
function TDIsMatchingCEFVersion: Boolean; forward;
|
||||||
|
procedure TDExecuteFullDownload; forward;
|
||||||
|
|
||||||
|
var IsPortable: Boolean;
|
||||||
|
var UpdatePath: String;
|
||||||
|
|
||||||
|
{ Check .NET Framework version on startup, ask user if they want to proceed if older than 4.5.2. Prepare full download package if required. }
|
||||||
|
function InitializeSetup: Boolean;
|
||||||
|
begin
|
||||||
|
IsPortable := ExpandConstant('{param:PORTABLE}') = '1'
|
||||||
|
UpdatePath := TDFindUpdatePath()
|
||||||
|
|
||||||
|
if UpdatePath = '' then
|
||||||
|
begin
|
||||||
|
MsgBox('{#MyAppName} installation could not be found on your system.', mbCriticalError, MB_OK);
|
||||||
|
Result := False;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if not TDIsMatchingCEFVersion() then
|
||||||
|
begin
|
||||||
|
idpAddFile('https://github.com/{#MyAppPublisher}/{#MyAppName}/releases/download/'+TDGetAppVersionClean()+'/{#MyAppName}.exe', ExpandConstant('{tmp}\{#MyAppName}.Full.exe'));
|
||||||
|
end;
|
||||||
|
|
||||||
|
if TDGetNetFrameworkVersion() >= 379893 then
|
||||||
|
begin
|
||||||
|
Result := True;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (MsgBox('{#MyAppName} requires .NET Framework 4.5.2 or newer,'+#13+#10+'please download it from {#MyAppURL}'+#13+#10+#13+#10'Do you want to proceed with the setup anyway?', mbCriticalError, MB_YESNO or MB_DEFBUTTON2) = IDNO) then
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Prepare download plugin if there are any files to download, and set the installation path. }
|
||||||
|
procedure InitializeWizard();
|
||||||
|
begin
|
||||||
|
WizardForm.DirEdit.Text := UpdatePath;
|
||||||
|
|
||||||
|
if idpFilesCount <> 0 then
|
||||||
|
begin
|
||||||
|
idpDownloadAfter(wpReady);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Ask user if they want to delete 'AppData\TweetDuck' and 'plugins' folders after uninstallation. }
|
||||||
|
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
|
||||||
|
var ProfileDataFolder: String;
|
||||||
|
var PluginDataFolder: String;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if CurUninstallStep = usPostUninstall then
|
||||||
|
begin
|
||||||
|
ProfileDataFolder := ExpandConstant('{localappdata}\{#MyAppName}');
|
||||||
|
PluginDataFolder := ExpandConstant('{app}\plugins');
|
||||||
|
|
||||||
|
if (DirExists(ProfileDataFolder) or DirExists(PluginDataFolder)) and (MsgBox('Do you also want to delete your {#MyAppName} profile and plugins?', mbConfirmation, MB_YESNO or MB_DEFBUTTON2) = IDYES) then
|
||||||
|
begin
|
||||||
|
DelTree(ProfileDataFolder, True, True, True);
|
||||||
|
DelTree(PluginDataFolder, True, True, True);
|
||||||
|
DelTree(ExpandConstant('{app}'), True, False, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Remove uninstallation data and application to force them to be replaced with updated ones. }
|
||||||
|
procedure CurStepChanged(CurStep: TSetupStep);
|
||||||
|
begin
|
||||||
|
if CurStep = ssInstall then
|
||||||
|
begin
|
||||||
|
TDExecuteFullDownload();
|
||||||
|
|
||||||
|
if TDIsUninstallable() then
|
||||||
|
begin
|
||||||
|
DeleteFile(ExpandConstant('{app}\unins000.dat'));
|
||||||
|
DeleteFile(ExpandConstant('{app}\unins000.exe'));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Returns true if the installer should create uninstallation entries (i.e. not running in portable mode). }
|
||||||
|
function TDIsUninstallable: Boolean;
|
||||||
|
begin
|
||||||
|
Result := not IsPortable
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Returns a validated installation path (including trailing backslash) using the /UPDATEPATH parameter or installation info in registry. Returns empty string on failure. }
|
||||||
|
function TDFindUpdatePath: String;
|
||||||
|
var Path: String;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Path := ExpandConstant('{param:UPDATEPATH}')
|
||||||
|
|
||||||
|
if (Path = '') and not IsPortable and not RegQueryStringValue(HKEY_LOCAL_MACHINE, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{{#MyAppID}}_is1', 'InstallLocation', Path) then
|
||||||
|
begin
|
||||||
|
Result := ''
|
||||||
|
Exit
|
||||||
|
end;
|
||||||
|
|
||||||
|
if not FileExists(Path+'{#MyAppExeName}') then
|
||||||
|
begin
|
||||||
|
Result := ''
|
||||||
|
Exit
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := Path
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Return DWORD value containing the build version of .NET Framework. }
|
||||||
|
function TDGetNetFrameworkVersion: Cardinal;
|
||||||
|
var FrameworkVersion: Cardinal;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if RegQueryDWordValue(HKEY_LOCAL_MACHINE, 'Software\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release', FrameworkVersion) then
|
||||||
|
begin
|
||||||
|
Result := FrameworkVersion;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Return whether the version of the installed libcef.dll library matches internal one. }
|
||||||
|
function TDIsMatchingCEFVersion: Boolean;
|
||||||
|
var CEFVersion: String;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result := (GetVersionNumbersString(UpdatePath+'libcef.dll', CEFVersion) and (CompareStr(CEFVersion, '{#CefVersion}') = 0))
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Return a cleaned up form of the app version string (removes all .0 suffixes). }
|
||||||
|
function TDGetAppVersionClean: String;
|
||||||
|
var Substr: String;
|
||||||
|
var CleanVersion: String;
|
||||||
|
|
||||||
|
begin
|
||||||
|
CleanVersion := '{#MyAppVersion}'
|
||||||
|
|
||||||
|
while True do
|
||||||
|
begin
|
||||||
|
Substr := Copy(CleanVersion, Length(CleanVersion)-1, 2);
|
||||||
|
|
||||||
|
if (CompareStr(Substr, '.0') <> 0) then
|
||||||
|
begin
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
|
||||||
|
CleanVersion := Copy(CleanVersion, 1, Length(CleanVersion)-2);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := CleanVersion;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Run the full package installer if downloaded. }
|
||||||
|
procedure TDExecuteFullDownload;
|
||||||
|
var InstallFile: String;
|
||||||
|
var ResultCode: Integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
InstallFile := ExpandConstant('{tmp}\{#MyAppName}.Full.exe')
|
||||||
|
|
||||||
|
if FileExists(InstallFile) then
|
||||||
|
begin
|
||||||
|
WizardForm.ProgressGauge.Style := npbstMarquee;
|
||||||
|
|
||||||
|
try
|
||||||
|
if Exec(InstallFile, '/SP- /SILENT /MERGETASKS="!desktopicon" /UPDATEPATH="'+UpdatePath+'"', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin
|
||||||
|
if ResultCode <> 0 then
|
||||||
|
begin
|
||||||
|
DeleteFile(InstallFile);
|
||||||
|
Abort();
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
MsgBox('Could not run the full installer, please visit {#MyAppURL} and download the latest version manually. Error: '+SysErrorMessage(ResultCode), mbCriticalError, MB_OK);
|
||||||
|
|
||||||
|
DeleteFile(InstallFile);
|
||||||
|
Abort();
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
WizardForm.ProgressGauge.Style := npbstNormal;
|
||||||
|
DeleteFile(InstallFile);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
Reference in New Issue
Block a user