diff --git a/renderdoccmd/renderdoccmd_win32.cpp b/renderdoccmd/renderdoccmd_win32.cpp index 143a6a411..47a7595bb 100644 --- a/renderdoccmd/renderdoccmd_win32.cpp +++ b/renderdoccmd/renderdoccmd_win32.cpp @@ -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; diff --git a/renderdocui/Code/AppMain.cs b/renderdocui/Code/AppMain.cs index 5e851fb99..191956864 100644 --- a/renderdocui/Code/AppMain.cs +++ b/renderdocui/Code/AppMain.cs @@ -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); diff --git a/renderdocui/Code/PersistantConfig.cs b/renderdocui/Code/PersistantConfig.cs index 48d363a7e..81be78343 100644 --- a/renderdocui/Code/PersistantConfig.cs +++ b/renderdocui/Code/PersistantConfig.cs @@ -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); diff --git a/renderdocui/Windows/Dialogs/UpdateDialog.Designer.cs b/renderdocui/Windows/Dialogs/UpdateDialog.Designer.cs new file mode 100644 index 000000000..1c45b215a --- /dev/null +++ b/renderdocui/Windows/Dialogs/UpdateDialog.Designer.cs @@ -0,0 +1,133 @@ +namespace renderdocui.Windows.Dialogs +{ + partial class UpdateDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + 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; + } +} \ No newline at end of file diff --git a/renderdocui/Windows/Dialogs/UpdateDialog.cs b/renderdocui/Windows/Dialogs/UpdateDialog.cs new file mode 100644 index 000000000..4d9fb4a5e --- /dev/null +++ b/renderdocui/Windows/Dialogs/UpdateDialog.cs @@ -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(); + } + } +} diff --git a/renderdocui/Windows/Dialogs/UpdateDialog.resx b/renderdocui/Windows/Dialogs/UpdateDialog.resx new file mode 100644 index 000000000..1af7de150 --- /dev/null +++ b/renderdocui/Windows/Dialogs/UpdateDialog.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/renderdocui/Windows/MainWindow.Designer.cs b/renderdocui/Windows/MainWindow.Designer.cs index 5c57f6865..458036f7a 100644 --- a/renderdocui/Windows/MainWindow.Designer.cs +++ b/renderdocui/Windows/MainWindow.Designer.cs @@ -28,21 +28,21 @@ /// 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; } } \ No newline at end of file diff --git a/renderdocui/Windows/MainWindow.cs b/renderdocui/Windows/MainWindow.cs index 5c5c8b9b7..67f61082b 100644 --- a/renderdocui/Windows/MainWindow.cs +++ b/renderdocui/Windows/MainWindow.cs @@ -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"); diff --git a/renderdocui/renderdocui.csproj b/renderdocui/renderdocui.csproj index 78afefe2c..46551cc37 100644 --- a/renderdocui/renderdocui.csproj +++ b/renderdocui/renderdocui.csproj @@ -264,6 +264,12 @@ TipsDialog.cs + + Form + + + UpdateDialog.cs + Form @@ -390,6 +396,9 @@ TipsDialog.cs + + UpdateDialog.cs + EventBrowser.cs