Add an update dialog that shows update notes & does upgrade smoothly

This commit is contained in:
baldurk
2015-08-30 00:11:48 +02:00
parent efc5c92e1a
commit 2d12d5abee
9 changed files with 767 additions and 89 deletions
+118
View File
@@ -298,6 +298,124 @@ int WINAPI wWinMain(_In_ HINSTANCE hInst,
return 1;
}
// special WIN32 option for launching the crash handler
if(argc == 3 && !_stricmp(argv[1], "--update"))
{
string originalpath = argv[2];
wstring wide_path;
{
wchar_t *conv = new wchar_t[originalpath.size()+1];
MultiByteToWideChar(CP_UTF8, 0, originalpath.c_str(), -1, conv, originalpath.size()+1);
wide_path = conv;
}
// Wait for UI to exit
Sleep(3000);
mz_zip_archive zip;
ZeroMemory(&zip, sizeof(zip));
mz_bool b = mz_zip_reader_init_file(&zip, "./update.zip", 0);
if(b)
{
mz_uint numfiles = mz_zip_reader_get_num_files(&zip);
// first create directories
for(mz_uint i=0; i < numfiles; i++)
{
if(mz_zip_reader_is_file_a_directory(&zip, i))
{
mz_zip_archive_file_stat zstat;
mz_zip_reader_file_stat(&zip, i, &zstat);
const char *fn = zstat.m_filename;
// skip first directory because it's RenderDoc_Version_Bitness/
fn = strchr(fn, '/');
if(fn) fn++;
if(*fn)
{
wchar_t conv[MAX_PATH] = {0};
wchar_t *wfn = conv;
// I know the zip only contains ASCII chars, just upcast
while(*fn) *(wfn++) = wchar_t(*(fn++));
wstring target = wide_path + conv;
wfn = &target[0];
// convert slashes because CreateDirectory barfs on
// proper slashes.
while(*(wfn++)) { if(*wfn == L'/') *wfn = L'\\'; }
CreateDirectoryW(target.c_str(), NULL);
}
}
}
for(mz_uint i=0; i < numfiles; i++)
{
if(!mz_zip_reader_is_file_a_directory(&zip, i))
{
mz_zip_archive_file_stat zstat;
mz_zip_reader_file_stat(&zip, i, &zstat);
const char *fn = zstat.m_filename;
// skip first directory because it's RenderDoc_Version_Bitness/
fn = strchr(fn, '/');
if(fn) fn++;
if(*fn)
{
wchar_t conv[MAX_PATH] = {0};
wchar_t *wfn = conv;
// I know the zip only contains ASCII chars, just upcast
while(*fn) *(wfn++) = wchar_t(*(fn++));
wstring target = wide_path + conv;
wfn = &target[0];
// convert slashes just to be consistent
while(*(wfn++)) { if(*wfn == L'/') *wfn = L'\\'; }
mz_zip_reader_extract_to_wfile(&zip, i, target.c_str(), 0);
}
}
}
}
// run original UI exe and tell it an update succeeded
wstring cmdline = L"\"";
cmdline += wide_path;
cmdline += L"/renderdocui.exe\" --updatedone";
wchar_t *paramsAlloc = new wchar_t[512];
wcscpy_s(paramsAlloc, 511, cmdline.c_str());
PROCESS_INFORMATION pi;
STARTUPINFOW si;
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
CreateProcessW(NULL, paramsAlloc, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
if(pi.dwProcessId != 0)
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
return 0;
}
#if defined(RELEASE)
CrashGenerationServer *crashServer = NULL;
+22
View File
@@ -62,6 +62,19 @@ namespace renderdocui.Code
Win32PInvoke.LoadLibrary("renderdoc.dll");
// clean up any update that just happened
string updateFilesPath = Path.Combine(Path.GetTempPath(), "RenderDocUpdate");
try
{
if (Directory.Exists(updateFilesPath))
Directory.Delete(updateFilesPath, true);
}
catch (Exception)
{
// ignore any exceptions from this
}
string filename = "";
bool temp = false;
@@ -136,6 +149,15 @@ namespace renderdocui.Code
var core = new Core(filename, remoteHost, remoteIdent, temp, cfg);
foreach (var a in args)
{
if (a.ToUpperInvariant() == "--UPDATEDONE")
{
cfg.CheckUpdate_UpdateAvailable = false;
cfg.CheckUpdate_UpdateResponse = "";
}
}
try
{
Application.Run(core.AppWindow);
+1
View File
@@ -102,6 +102,7 @@ namespace renderdocui.Code
public bool CheckUpdate_AllowChecks = true;
public bool CheckUpdate_UpdateAvailable = false;
public string CheckUpdate_UpdateResponse = "";
public DateTime CheckUpdate_LastUpdate = new DateTime(2012, 06, 27);
public DateTime DegradedLog_LastUpdate = new DateTime(2015, 01, 01);
+133
View File
@@ -0,0 +1,133 @@
namespace renderdocui.Windows.Dialogs
{
partial class UpdateDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.updateVer = new System.Windows.Forms.Label();
this.updateNotes = new System.Windows.Forms.TextBox();
this.progressBar = new System.Windows.Forms.ProgressBar();
this.doupdate = new System.Windows.Forms.Button();
this.progressText = new System.Windows.Forms.Label();
this.close = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// updateVer
//
this.updateVer.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.updateVer.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.updateVer.Location = new System.Drawing.Point(10, 9);
this.updateVer.Name = "updateVer";
this.updateVer.Size = new System.Drawing.Size(376, 25);
this.updateVer.TabIndex = 1;
this.updateVer.Text = "Update Available - v0.00-betahash";
this.updateVer.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// updateNotes
//
this.updateNotes.BackColor = System.Drawing.SystemColors.Window;
this.updateNotes.Location = new System.Drawing.Point(15, 37);
this.updateNotes.Multiline = true;
this.updateNotes.Name = "updateNotes";
this.updateNotes.ReadOnly = true;
this.updateNotes.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.updateNotes.Size = new System.Drawing.Size(363, 194);
this.updateNotes.TabIndex = 2;
//
// progressBar
//
this.progressBar.Location = new System.Drawing.Point(131, 244);
this.progressBar.Name = "progressBar";
this.progressBar.Size = new System.Drawing.Size(249, 23);
this.progressBar.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
this.progressBar.TabIndex = 3;
//
// doupdate
//
this.doupdate.Location = new System.Drawing.Point(212, 273);
this.doupdate.Name = "doupdate";
this.doupdate.Size = new System.Drawing.Size(168, 23);
this.doupdate.TabIndex = 4;
this.doupdate.Text = "Download, restart and Install";
this.doupdate.UseVisualStyleBackColor = true;
this.doupdate.Click += new System.EventHandler(this.doupdate_Click);
//
// progressText
//
this.progressText.AutoSize = true;
this.progressText.Location = new System.Drawing.Point(15, 249);
this.progressText.Name = "progressText";
this.progressText.Size = new System.Drawing.Size(78, 13);
this.progressText.TabIndex = 5;
this.progressText.Text = "Downloading...";
//
// close
//
this.close.Location = new System.Drawing.Point(131, 273);
this.close.Name = "close";
this.close.Size = new System.Drawing.Size(75, 23);
this.close.TabIndex = 6;
this.close.Text = "Close";
this.close.UseVisualStyleBackColor = true;
this.close.Click += new System.EventHandler(this.close_Click);
//
// UpdateDialog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(392, 308);
this.Controls.Add(this.close);
this.Controls.Add(this.progressText);
this.Controls.Add(this.doupdate);
this.Controls.Add(this.progressBar);
this.Controls.Add(this.updateNotes);
this.Controls.Add(this.updateVer);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "UpdateDialog";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Update Available";
this.TopMost = true;
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label updateVer;
private System.Windows.Forms.TextBox updateNotes;
private System.Windows.Forms.ProgressBar progressBar;
private System.Windows.Forms.Button doupdate;
private System.Windows.Forms.Label progressText;
private System.Windows.Forms.Button close;
}
}
+159
View File
@@ -0,0 +1,159 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Threading;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using renderdocui.Code;
using System.Diagnostics;
namespace renderdocui.Windows.Dialogs
{
public partial class UpdateDialog : Form
{
// http://www.codeproject.com/Articles/18509/Add-a-UAC-shield-to-a-button-when-elevation-is-req
[DllImport("user32")]
public static extern UInt32 SendMessage(IntPtr hWnd, UInt32 msg, UInt32 wParam, UInt32 lParam);
internal const int BCM_SETSHIELD = 0x160C; // Button needs elevation
string m_URL = "";
int m_Size = 0;
public UpdateDialog(Core core)
{
InitializeComponent();
doupdate.FlatStyle = FlatStyle.System;
SendMessage(doupdate.Handle, BCM_SETSHIELD, 0, 0xFFFFFFFF);
string[] response_split = core.Config.CheckUpdate_UpdateResponse.Split('\n');
progressText.Text = "";
updateVer.Text = String.Format("Update Available - v{0}", response_split[0]);
m_URL = response_split[1];
int.TryParse(response_split[2], out m_Size);
string notes = "";
for(int i=3; i < response_split.Length; i++)
notes += response_split[i] + Environment.NewLine;
updateNotes.Text = notes.Trim();
updateNotes.Select(0, 0);
}
void SetDownloadProgress(int bytes_received)
{
progressText.Text = "Downloading Update";
if(m_Size > 0)
progressBar.Value = (int)(progressBar.Maximum * ((float)bytes_received / (float)m_Size));
}
private void doupdate_Click(object sender, EventArgs e)
{
DialogResult result = MessageBox.Show("This will close RenderDoc immediately - if you have any unsaved work, save it first!\nContinue?", "RenderDoc Update", MessageBoxButtons.YesNoCancel);
if (result == DialogResult.Yes)
{
progressText.Text = "Connecting";
close.Enabled = false;
doupdate.Enabled = false;
var updateThread = Helpers.NewThread(new ThreadStart(() =>
{
HttpWebRequest g = (HttpWebRequest)HttpWebRequest.Create(m_URL);
g.Method = "GET";
string dstpath = Path.Combine(Path.GetTempPath(), "RenderDocUpdate");
string destzip = Path.Combine(dstpath, "update.zip");
Directory.CreateDirectory(Path.GetDirectoryName(destzip));
g.BeginGetResponse(new AsyncCallback((IAsyncResult asyncres) =>
{
int recvd = 0;
try
{
using (HttpWebResponse resp = (HttpWebResponse)g.EndGetResponse(asyncres))
{
byte[] buffer = new byte[1024];
FileStream strm = File.OpenWrite(destzip);
using (Stream input = resp.GetResponseStream())
{
int size = input.Read(buffer, 0, buffer.Length);
while (size > 0)
{
strm.Write(buffer, 0, size);
recvd += size;
size = input.Read(buffer, 0, buffer.Length);
BeginInvoke((MethodInvoker)delegate
{
SetDownloadProgress(recvd);
});
}
}
strm.Flush();
strm.Close();
}
}
catch (Exception)
{
BeginInvoke((MethodInvoker)delegate
{
MessageBox.Show("Error downloading update files! Try again later", "Error downloading", MessageBoxButtons.OK, MessageBoxIcon.Error);
Close();
});
return;
}
string srcpath = Path.GetDirectoryName(Application.ExecutablePath);
BeginInvoke((MethodInvoker)delegate
{
progressText.Text = "Installing";
File.Copy(Path.Combine(srcpath, "renderdoc.dll"), Path.Combine(dstpath, "renderdoc.dll"), true);
File.Copy(Path.Combine(srcpath, "renderdoccmd.exe"), Path.Combine(dstpath, "renderdoccmd.exe"), true);
var process = new Process();
process.StartInfo = new ProcessStartInfo(Path.Combine(dstpath, "renderdoccmd.exe"), "--update \"" + srcpath.Replace('\\', '/') + "/\"");
process.StartInfo.WorkingDirectory = dstpath;
process.StartInfo.Verb = "runas"; // need to run as admin to have write permissions
try
{
process.Start();
Application.Exit();
}
catch (Exception)
{
// if there was an exception, display an error and don't exit.
MessageBox.Show("Unknown error encountered while trying to launch updater!", "Error updating", MessageBoxButtons.OK, MessageBoxIcon.Error);
Close();
}
});
}), g);
}));
updateThread.Start();
}
}
private void close_Click(object sender, EventArgs e)
{
Close();
}
}
}
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+79 -68
View File
@@ -28,21 +28,21 @@
/// </summary>
private void InitializeComponent()
{
WeifenLuo.WinFormsUI.Docking.DockPanelSkin dockPanelSkin1 = new WeifenLuo.WinFormsUI.Docking.DockPanelSkin();
WeifenLuo.WinFormsUI.Docking.AutoHideStripSkin autoHideStripSkin1 = new WeifenLuo.WinFormsUI.Docking.AutoHideStripSkin();
WeifenLuo.WinFormsUI.Docking.DockPanelGradient dockPanelGradient1 = new WeifenLuo.WinFormsUI.Docking.DockPanelGradient();
WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient1 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
WeifenLuo.WinFormsUI.Docking.DockPaneStripSkin dockPaneStripSkin1 = new WeifenLuo.WinFormsUI.Docking.DockPaneStripSkin();
WeifenLuo.WinFormsUI.Docking.DockPaneStripGradient dockPaneStripGradient1 = new WeifenLuo.WinFormsUI.Docking.DockPaneStripGradient();
WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient2 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
WeifenLuo.WinFormsUI.Docking.DockPanelGradient dockPanelGradient2 = new WeifenLuo.WinFormsUI.Docking.DockPanelGradient();
WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient3 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
WeifenLuo.WinFormsUI.Docking.DockPaneStripToolWindowGradient dockPaneStripToolWindowGradient1 = new WeifenLuo.WinFormsUI.Docking.DockPaneStripToolWindowGradient();
WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient4 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient5 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
WeifenLuo.WinFormsUI.Docking.DockPanelGradient dockPanelGradient3 = new WeifenLuo.WinFormsUI.Docking.DockPanelGradient();
WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient6 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient7 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
WeifenLuo.WinFormsUI.Docking.DockPanelSkin dockPanelSkin2 = new WeifenLuo.WinFormsUI.Docking.DockPanelSkin();
WeifenLuo.WinFormsUI.Docking.AutoHideStripSkin autoHideStripSkin2 = new WeifenLuo.WinFormsUI.Docking.AutoHideStripSkin();
WeifenLuo.WinFormsUI.Docking.DockPanelGradient dockPanelGradient4 = new WeifenLuo.WinFormsUI.Docking.DockPanelGradient();
WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient8 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
WeifenLuo.WinFormsUI.Docking.DockPaneStripSkin dockPaneStripSkin2 = new WeifenLuo.WinFormsUI.Docking.DockPaneStripSkin();
WeifenLuo.WinFormsUI.Docking.DockPaneStripGradient dockPaneStripGradient2 = new WeifenLuo.WinFormsUI.Docking.DockPaneStripGradient();
WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient9 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
WeifenLuo.WinFormsUI.Docking.DockPanelGradient dockPanelGradient5 = new WeifenLuo.WinFormsUI.Docking.DockPanelGradient();
WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient10 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
WeifenLuo.WinFormsUI.Docking.DockPaneStripToolWindowGradient dockPaneStripToolWindowGradient2 = new WeifenLuo.WinFormsUI.Docking.DockPaneStripToolWindowGradient();
WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient11 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient12 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
WeifenLuo.WinFormsUI.Docking.DockPanelGradient dockPanelGradient6 = new WeifenLuo.WinFormsUI.Docking.DockPanelGradient();
WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient13 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
WeifenLuo.WinFormsUI.Docking.TabGradient tabGradient14 = new WeifenLuo.WinFormsUI.Docking.TabGradient();
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.captureLogToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -94,6 +94,7 @@
this.logStatisticsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator11 = new System.Windows.Forms.ToolStripSeparator();
this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.manageReplayDevicesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.viewDocsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.viewLogFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -112,7 +113,7 @@
this.statusProgress = new System.Windows.Forms.ToolStripProgressBar();
this.dockPanel = new WeifenLuo.WinFormsUI.Docking.DockPanel();
this.saveDialog = new System.Windows.Forms.SaveFileDialog();
this.manageReplayDevicesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.checkForUpdatesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menuStrip1.SuspendLayout();
this.toolStripContainer1.BottomToolStripPanel.SuspendLayout();
this.toolStripContainer1.ContentPanel.SuspendLayout();
@@ -535,6 +536,13 @@
this.optionsToolStripMenuItem.Text = "&Options";
this.optionsToolStripMenuItem.Click += new System.EventHandler(this.optionsToolStripMenuItem_Click);
//
// manageReplayDevicesToolStripMenuItem
//
this.manageReplayDevicesToolStripMenuItem.Name = "manageReplayDevicesToolStripMenuItem";
this.manageReplayDevicesToolStripMenuItem.Size = new System.Drawing.Size(188, 22);
this.manageReplayDevicesToolStripMenuItem.Text = "&Manage Replay Devices";
this.manageReplayDevicesToolStripMenuItem.Click += new System.EventHandler(this.manageReplayDevicesToolStripMenuItem_Click);
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -542,6 +550,7 @@
this.viewLogFileToolStripMenuItem,
this.sendErrorReportToolStripMenuItem,
this.toolStripSeparator9,
this.checkForUpdatesToolStripMenuItem,
this.updateToolStripMenuItem,
this.toolStripSeparator8,
this.sourceOnGithubToolStripMenuItem,
@@ -620,7 +629,8 @@
// openDialog
//
this.openDialog.DefaultExt = "rdc";
this.openDialog.Filter = "Log Files (*.rdc)|*.rdc|Image Files|*.dds;*.hdr;*.exr;*.bmp;*.jpg;*.jpeg;*.png;*.tga;*.gif;*.psd|All Files (*.*)|*.*";
this.openDialog.Filter = "Log Files (*.rdc)|*.rdc|Image Files|*.dds;*.hdr;*.exr;*.bmp;*.jpg;*.jpeg;*.png;*." +
"tga;*.gif;*.psd|All Files (*.*)|*.*";
this.openDialog.Title = "Select Logfile to open";
//
// toolStripContainer1
@@ -695,52 +705,52 @@
this.dockPanel.Location = new System.Drawing.Point(0, 0);
this.dockPanel.Name = "dockPanel";
this.dockPanel.Size = new System.Drawing.Size(1272, 727);
dockPanelGradient1.EndColor = System.Drawing.SystemColors.ControlLight;
dockPanelGradient1.StartColor = System.Drawing.SystemColors.ControlLight;
autoHideStripSkin1.DockStripGradient = dockPanelGradient1;
tabGradient1.EndColor = System.Drawing.SystemColors.Control;
tabGradient1.StartColor = System.Drawing.SystemColors.Control;
tabGradient1.TextColor = System.Drawing.SystemColors.ControlDarkDark;
autoHideStripSkin1.TabGradient = tabGradient1;
autoHideStripSkin1.TextFont = new System.Drawing.Font("Tahoma", 8.25F);
dockPanelSkin1.AutoHideStripSkin = autoHideStripSkin1;
tabGradient2.EndColor = System.Drawing.SystemColors.ControlLightLight;
tabGradient2.StartColor = System.Drawing.SystemColors.ControlLightLight;
tabGradient2.TextColor = System.Drawing.SystemColors.ControlText;
dockPaneStripGradient1.ActiveTabGradient = tabGradient2;
dockPanelGradient2.EndColor = System.Drawing.SystemColors.Control;
dockPanelGradient2.StartColor = System.Drawing.SystemColors.Control;
dockPaneStripGradient1.DockStripGradient = dockPanelGradient2;
tabGradient3.EndColor = System.Drawing.SystemColors.ControlLight;
tabGradient3.StartColor = System.Drawing.SystemColors.ControlLight;
tabGradient3.TextColor = System.Drawing.SystemColors.ControlText;
dockPaneStripGradient1.InactiveTabGradient = tabGradient3;
dockPaneStripSkin1.DocumentGradient = dockPaneStripGradient1;
dockPaneStripSkin1.TextFont = new System.Drawing.Font("Tahoma", 8.25F);
tabGradient4.EndColor = System.Drawing.SystemColors.ActiveCaption;
tabGradient4.LinearGradientMode = System.Drawing.Drawing2D.LinearGradientMode.Vertical;
tabGradient4.StartColor = System.Drawing.SystemColors.GradientActiveCaption;
tabGradient4.TextColor = System.Drawing.SystemColors.ActiveCaptionText;
dockPaneStripToolWindowGradient1.ActiveCaptionGradient = tabGradient4;
tabGradient5.EndColor = System.Drawing.SystemColors.Control;
tabGradient5.StartColor = System.Drawing.SystemColors.Control;
tabGradient5.TextColor = System.Drawing.SystemColors.ControlText;
dockPaneStripToolWindowGradient1.ActiveTabGradient = tabGradient5;
dockPanelGradient3.EndColor = System.Drawing.SystemColors.ControlLight;
dockPanelGradient3.StartColor = System.Drawing.SystemColors.ControlLight;
dockPaneStripToolWindowGradient1.DockStripGradient = dockPanelGradient3;
tabGradient6.EndColor = System.Drawing.SystemColors.InactiveCaption;
tabGradient6.LinearGradientMode = System.Drawing.Drawing2D.LinearGradientMode.Vertical;
tabGradient6.StartColor = System.Drawing.SystemColors.GradientInactiveCaption;
tabGradient6.TextColor = System.Drawing.SystemColors.InactiveCaptionText;
dockPaneStripToolWindowGradient1.InactiveCaptionGradient = tabGradient6;
tabGradient7.EndColor = System.Drawing.Color.Transparent;
tabGradient7.StartColor = System.Drawing.Color.Transparent;
tabGradient7.TextColor = System.Drawing.SystemColors.ControlDarkDark;
dockPaneStripToolWindowGradient1.InactiveTabGradient = tabGradient7;
dockPaneStripSkin1.ToolWindowGradient = dockPaneStripToolWindowGradient1;
dockPanelSkin1.DockPaneStripSkin = dockPaneStripSkin1;
this.dockPanel.Skin = dockPanelSkin1;
dockPanelGradient4.EndColor = System.Drawing.SystemColors.ControlLight;
dockPanelGradient4.StartColor = System.Drawing.SystemColors.ControlLight;
autoHideStripSkin2.DockStripGradient = dockPanelGradient4;
tabGradient8.EndColor = System.Drawing.SystemColors.Control;
tabGradient8.StartColor = System.Drawing.SystemColors.Control;
tabGradient8.TextColor = System.Drawing.SystemColors.ControlDarkDark;
autoHideStripSkin2.TabGradient = tabGradient8;
autoHideStripSkin2.TextFont = new System.Drawing.Font("Tahoma", 8.25F);
dockPanelSkin2.AutoHideStripSkin = autoHideStripSkin2;
tabGradient9.EndColor = System.Drawing.SystemColors.ControlLightLight;
tabGradient9.StartColor = System.Drawing.SystemColors.ControlLightLight;
tabGradient9.TextColor = System.Drawing.SystemColors.ControlText;
dockPaneStripGradient2.ActiveTabGradient = tabGradient9;
dockPanelGradient5.EndColor = System.Drawing.SystemColors.Control;
dockPanelGradient5.StartColor = System.Drawing.SystemColors.Control;
dockPaneStripGradient2.DockStripGradient = dockPanelGradient5;
tabGradient10.EndColor = System.Drawing.SystemColors.ControlLight;
tabGradient10.StartColor = System.Drawing.SystemColors.ControlLight;
tabGradient10.TextColor = System.Drawing.SystemColors.ControlText;
dockPaneStripGradient2.InactiveTabGradient = tabGradient10;
dockPaneStripSkin2.DocumentGradient = dockPaneStripGradient2;
dockPaneStripSkin2.TextFont = new System.Drawing.Font("Tahoma", 8.25F);
tabGradient11.EndColor = System.Drawing.SystemColors.ActiveCaption;
tabGradient11.LinearGradientMode = System.Drawing.Drawing2D.LinearGradientMode.Vertical;
tabGradient11.StartColor = System.Drawing.SystemColors.GradientActiveCaption;
tabGradient11.TextColor = System.Drawing.SystemColors.ActiveCaptionText;
dockPaneStripToolWindowGradient2.ActiveCaptionGradient = tabGradient11;
tabGradient12.EndColor = System.Drawing.SystemColors.Control;
tabGradient12.StartColor = System.Drawing.SystemColors.Control;
tabGradient12.TextColor = System.Drawing.SystemColors.ControlText;
dockPaneStripToolWindowGradient2.ActiveTabGradient = tabGradient12;
dockPanelGradient6.EndColor = System.Drawing.SystemColors.ControlLight;
dockPanelGradient6.StartColor = System.Drawing.SystemColors.ControlLight;
dockPaneStripToolWindowGradient2.DockStripGradient = dockPanelGradient6;
tabGradient13.EndColor = System.Drawing.SystemColors.InactiveCaption;
tabGradient13.LinearGradientMode = System.Drawing.Drawing2D.LinearGradientMode.Vertical;
tabGradient13.StartColor = System.Drawing.SystemColors.GradientInactiveCaption;
tabGradient13.TextColor = System.Drawing.SystemColors.InactiveCaptionText;
dockPaneStripToolWindowGradient2.InactiveCaptionGradient = tabGradient13;
tabGradient14.EndColor = System.Drawing.Color.Transparent;
tabGradient14.StartColor = System.Drawing.Color.Transparent;
tabGradient14.TextColor = System.Drawing.SystemColors.ControlDarkDark;
dockPaneStripToolWindowGradient2.InactiveTabGradient = tabGradient14;
dockPaneStripSkin2.ToolWindowGradient = dockPaneStripToolWindowGradient2;
dockPanelSkin2.DockPaneStripSkin = dockPaneStripSkin2;
this.dockPanel.Skin = dockPanelSkin2;
this.dockPanel.TabIndex = 0;
//
// saveDialog
@@ -749,12 +759,12 @@
this.saveDialog.Filter = "Log Files (*.rdc)|*.rdc";
this.saveDialog.Title = "Save Log As";
//
// manageReplayDevicesToolStripMenuItem
// checkForUpdatesToolStripMenuItem
//
this.manageReplayDevicesToolStripMenuItem.Name = "manageReplayDevicesToolStripMenuItem";
this.manageReplayDevicesToolStripMenuItem.Size = new System.Drawing.Size(188, 22);
this.manageReplayDevicesToolStripMenuItem.Text = "&Manage Replay Devices";
this.manageReplayDevicesToolStripMenuItem.Click += new System.EventHandler(this.manageReplayDevicesToolStripMenuItem_Click);
this.checkForUpdatesToolStripMenuItem.Name = "checkForUpdatesToolStripMenuItem";
this.checkForUpdatesToolStripMenuItem.Size = new System.Drawing.Size(192, 22);
this.checkForUpdatesToolStripMenuItem.Text = "Check for Updates";
this.checkForUpdatesToolStripMenuItem.Click += new System.EventHandler(this.checkForUpdatesToolStripMenuItem_Click);
//
// MainWindow
//
@@ -860,6 +870,7 @@
private System.Windows.Forms.ToolStripMenuItem pythonShellToolStripMenuItem;
private System.Windows.Forms.ToolStripStatusLabel statusIcon;
private System.Windows.Forms.ToolStripMenuItem manageReplayDevicesToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem checkForUpdatesToolStripMenuItem;
}
}
+126 -21
View File
@@ -119,6 +119,14 @@ namespace renderdocui.Windows
}
}
private string BareVersionString
{
get
{
return Assembly.GetEntryAssembly().GetName().Version.ToString(2);
}
}
private string VersionString
{
get
@@ -975,34 +983,77 @@ namespace renderdocui.Windows
updateToolStripMenuItem.Text = "An update is available";
}
private void CheckUpdates()
private void UpdatePopup()
{
if (!m_Core.Config.CheckUpdate_AllowChecks)
(new Dialogs.UpdateDialog(m_Core)).ShowDialog();
}
private enum UpdateResult
{
Disabled,
Unofficial,
Toosoon,
Latest,
Upgrade,
};
private delegate void UpdateResultMethod(UpdateResult res);
private void CheckUpdates(bool forceCheck = false, UpdateResultMethod callback = null)
{
if (!forceCheck && !m_Core.Config.CheckUpdate_AllowChecks)
{
updateToolStripMenuItem.Text = "Update checks disabled";
if (callback != null) callback(UpdateResult.Disabled);
return;
}
if(!OfficialVersion && !BetaVersion)
if (!OfficialVersion && !BetaVersion)
{
if (callback != null) callback(UpdateResult.Unofficial);
return;
}
if (m_Core.Config.CheckUpdate_UpdateAvailable)
{
if (m_Core.Config.CheckUpdate_UpdateResponse.Length == 0)
{
forceCheck = true;
}
else
{
SetUpdateAvailable();
return;
}
}
DateTime today = DateTime.Now;
DateTime compare = today.AddDays(-2);
if(compare.CompareTo(m_Core.Config.CheckUpdate_LastUpdate) < 0)
if (!forceCheck && compare.CompareTo(m_Core.Config.CheckUpdate_LastUpdate) < 0)
{
if (callback != null) callback(UpdateResult.Toosoon);
return;
}
m_Core.Config.CheckUpdate_LastUpdate = today;
string versionCheck = VersionString;
string versionCheck = BareVersionString;
if (BetaVersion)
versionCheck += String.Format("-{0}-beta", GitCommitHash.Substring(0, 8));
statusText.Text = "Checking for updates...";
statusProgress.Visible = true;
statusProgress.Style = ProgressBarStyle.Marquee;
statusProgress.MarqueeAnimationSpeed = 50;
var updateThread = Helpers.NewThread(new ThreadStart(() =>
{
// spawn thread to check update
WebRequest g = HttpWebRequest.Create(String.Format("http://renderdoc.org/checkupdate/{0}", versionCheck));
WebRequest g = HttpWebRequest.Create(String.Format("http://renderdoc.org/getupdateurl/{0}/{1}", IntPtr.Size == 4 ? "32" : "64", versionCheck));
UpdateResult result = UpdateResult.Disabled;
try
{
@@ -1012,8 +1063,21 @@ namespace renderdocui.Windows
{
string response = sr.ReadToEnd();
if (response == "update")
BeginInvoke((MethodInvoker)delegate { m_Core.Config.CheckUpdate_UpdateAvailable = true; SetUpdateAvailable(); });
if (response != "")
{
BeginInvoke((MethodInvoker)delegate
{
m_Core.Config.CheckUpdate_UpdateAvailable = true;
m_Core.Config.CheckUpdate_UpdateResponse = response;
SetUpdateAvailable();
UpdatePopup();
});
result = UpdateResult.Upgrade;
}
else if (callback != null)
{
result = UpdateResult.Latest;
}
}
webresp.Close();
@@ -1021,19 +1085,70 @@ namespace renderdocui.Windows
catch (WebException ex)
{
StaticExports.LogText(String.Format("Problem checking for updates - {0}", ex.Message));
return;
}
catch (Exception)
{
// just want to swallow the exception, checking for updates doesn't need to be handled
// and it's not worth trying to retry.
return;
}
BeginInvoke((MethodInvoker)delegate
{
statusText.Text = "";
statusProgress.Visible = false;
statusProgress.Style = ProgressBarStyle.Continuous;
statusProgress.MarqueeAnimationSpeed = 0;
if (callback != null && result != UpdateResult.Disabled)
callback(result);
});
}));
updateThread.Start();
}
private void checkForUpdatesToolStripMenuItem_Click(object sender, EventArgs e)
{
CheckUpdates(true, (UpdateResult res) =>
{
switch (res)
{
case UpdateResult.Disabled:
case UpdateResult.Toosoon:
{
// won't happen, we forced the check
break;
}
case UpdateResult.Unofficial:
{
DialogResult mb = MessageBox.Show("You are running an unofficial build, not beta or stable release.\n" +
"Updates are only available for installed release builds\n\n" +
"Would you like to open the builds list in a browser?",
"Unofficial build", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (mb == DialogResult.Yes)
Process.Start("https://renderdoc.org/builds");
break;
}
case UpdateResult.Latest:
{
MessageBox.Show("You are running the latest version.\n", "Latest version", MessageBoxButtons.OK, MessageBoxIcon.Information);
break;
}
case UpdateResult.Upgrade:
{
// CheckUpdates() will have shown a dialog for this
break;
}
}
});
}
private void updateToolStripMenuItem_Click(object sender, EventArgs e)
{
SetUpdateAvailable();
UpdatePopup();
}
private bool PromptCloseLog()
{
string deletepath = "";
@@ -1451,16 +1566,6 @@ namespace renderdocui.Windows
Help.ShowHelp(this, "renderdoc.chm");
}
private void updateToolStripMenuItem_Click(object sender, EventArgs e)
{
Process.Start(String.Format("http://renderdoc.org/getupdate/{0}", VersionString));
DateTime today = DateTime.Now;
m_Core.Config.CheckUpdate_LastUpdate = today;
m_Core.Config.CheckUpdate_UpdateAvailable = false;
}
private void nightlybuildsToolStripMenuItem_Click(object sender, EventArgs e)
{
Process.Start("https://renderdoc.org/builds");
+9
View File
@@ -264,6 +264,12 @@
<Compile Include="Windows\Dialogs\TipsDialog.Designer.cs">
<DependentUpon>TipsDialog.cs</DependentUpon>
</Compile>
<Compile Include="Windows\Dialogs\UpdateDialog.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Windows\Dialogs\UpdateDialog.Designer.cs">
<DependentUpon>UpdateDialog.cs</DependentUpon>
</Compile>
<Compile Include="Windows\EventBrowser.cs">
<SubType>Form</SubType>
</Compile>
@@ -390,6 +396,9 @@
<EmbeddedResource Include="Windows\Dialogs\TipsDialog.resx">
<DependentUpon>TipsDialog.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Windows\Dialogs\UpdateDialog.resx">
<DependentUpon>UpdateDialog.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Windows\EventBrowser.resx">
<DependentUpon>EventBrowser.cs</DependentUpon>
</EmbeddedResource>