Browse Source
- added "ProfileExecutable" dialog - replaced ProfilerService with ProfilerRunner git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3887 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
12 changed files with 324 additions and 188 deletions
@ -1,34 +1,19 @@
@@ -1,34 +1,19 @@
|
||||
<Window x:Class="ICSharpCode.Profiler.AddIn.Dialogs.ProfileExecutableForm" |
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
Height="510" Width="621" Title="Profile executable"> |
||||
<ScrollViewer VerticalScrollBarVisibility="Auto"> |
||||
<StackPanel> |
||||
<Expander Header="General Information" Name="expander1"> |
||||
<Grid Height="103"> |
||||
<Label HorizontalAlignment="Left" Margin="6,6,0,0" Name="label1" Width="112" Height="24" VerticalAlignment="Top">Path to executable:</Label> |
||||
<TextBox Margin="124,6,50,0" Name="textBox1" Height="26" VerticalAlignment="Top" /> |
||||
<Button Height="26" Margin="0,6,6,0" Name="button1" VerticalAlignment="Top" HorizontalAlignment="Right" Width="38">...</Button> |
||||
<Label Height="26" HorizontalAlignment="Left" Margin="6,36,0,0" Name="label2" VerticalAlignment="Top" Width="112">Working directory:</Label> |
||||
<TextBox Height="26" Margin="124,36,50,0" Name="textBox2" VerticalAlignment="Top" /> |
||||
<Button Height="26" HorizontalAlignment="Right" Margin="0,36,6,0" Name="button2" VerticalAlignment="Top" Width="38">...</Button> |
||||
<Label Height="26" HorizontalAlignment="Left" Margin="6,68,0,0" Name="label3" VerticalAlignment="Top" Width="112">Arguments:</Label> |
||||
<TextBox Height="26" Margin="124,68,6,0" Name="textBox3" VerticalAlignment="Top" /> |
||||
</Grid> |
||||
</Expander> |
||||
<Expander Header="Select Profiler Mode" Name="expander2"> |
||||
<Grid Height="60"> |
||||
<RadioButton HorizontalAlignment="Left" Margin="6,6,0,0" Name="radioButton1" Width="175" Height="20" VerticalAlignment="Top">Performance Profiling</RadioButton> |
||||
<RadioButton HorizontalAlignment="Left" Margin="6,0,0,6" Name="radioButton2" Width="175" Height="22" VerticalAlignment="Bottom" IsEnabled="False">Memory Profiling</RadioButton> |
||||
</Grid> |
||||
</Expander> |
||||
<Expander Header="Choose Output" Name="expander3"> |
||||
<Grid Height="226"> |
||||
<RadioButton Margin="6,6,134,201" Name="radioButton3">Use custom directory:</RadioButton> |
||||
<TextBox Height="26" Margin="21,31,0,0" Name="textBox4" VerticalAlignment="Top" HorizontalAlignment="Left" Width="526" IsEnabled="{Binding IsChecked, ElementName=radioButton3}" /> |
||||
<Button Height="26" HorizontalAlignment="Right" Margin="0,31,6,0" Name="button3" VerticalAlignment="Top" Width="38">...</Button> |
||||
</Grid> |
||||
</Expander> |
||||
</StackPanel> |
||||
</ScrollViewer> |
||||
Height="195" Width="609" Title="Profile executable" WindowStartupLocation="CenterScreen" WindowStyle="ToolWindow" ShowInTaskbar="False" ResizeMode="NoResize"> |
||||
<Grid Background="#FFD4D0C8"> |
||||
<Label HorizontalAlignment="Left" Margin="12,46,0,0" Width="145" Height="24" VerticalAlignment="Top">Path to executable:</Label> |
||||
<TextBox Margin="163,44,56,0" Name="txtExePath" Height="26" VerticalAlignment="Top" /> |
||||
<Button Height="26" Margin="0,45.138,12,0" VerticalAlignment="Top" HorizontalAlignment="Right" Width="38" Click="btnSelectFileClick">...</Button> |
||||
<Label Height="26" HorizontalAlignment="Left" Margin="12,76,0,0" VerticalAlignment="Top" Width="145">Working directory:</Label> |
||||
<TextBox Height="26" Margin="163,77,56,0" Name="txtWorkingDir" VerticalAlignment="Top" /> |
||||
<Button Height="26" HorizontalAlignment="Right" Margin="0,76,12,0" VerticalAlignment="Top" Width="38" Click="btnSelectDirClick">...</Button> |
||||
<Label Height="26" HorizontalAlignment="Left" Margin="12,108,0,0" VerticalAlignment="Top" Width="145">Command-Line Arguments:</Label> |
||||
<TextBlock Height="36" Margin="12,12,12,0" VerticalAlignment="Top" |
||||
Text="Select the path of the executable you want to profile. Optionally you can specify working directory and command line arguments to start the process." TextWrapping="Wrap" /> |
||||
<TextBox Margin="163,109,12,0" Name="txtArgs" VerticalAlignment="Top" Height="24" /> |
||||
<Button Height="27" HorizontalAlignment="Left" Margin="173,0,0,6" VerticalAlignment="Bottom" Width="105" Click="btnStartClick">Start Profiling</Button> |
||||
<Button Height="27" Margin="0,0,204,6" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="99" Click="btnCancelClick">Cancel</Button> |
||||
</Grid> |
||||
</Window> |
||||
|
@ -1,27 +1,114 @@
@@ -1,27 +1,114 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Diagnostics; |
||||
using System.Globalization; |
||||
using System.IO; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Data; |
||||
using System.Windows.Documents; |
||||
using System.Windows.Input; |
||||
using System.Windows.Media; |
||||
using System.Windows.Media.Imaging; |
||||
using System.Windows.Navigation; |
||||
using System.Windows.Shapes; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.Profiler.AddIn.OptionsPanels; |
||||
using ICSharpCode.Profiler.AddIn.Views; |
||||
using ICSharpCode.Profiler.Controller.Data; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using Microsoft.Win32; |
||||
|
||||
namespace ICSharpCode.Profiler.AddIn.Dialogs |
||||
{ |
||||
/// <summary>
|
||||
/// Interaktionslogik für ProfileExecutableForm.xaml
|
||||
/// </summary>
|
||||
public partial class ProfileExecutableForm : Window |
||||
{ |
||||
public ProfileExecutableForm() |
||||
{ |
||||
InitializeComponent(); |
||||
} |
||||
} |
||||
/// <summary>
|
||||
/// Interaktionslogik für ProfileExecutableForm.xaml
|
||||
/// </summary>
|
||||
public partial class ProfileExecutableForm : Window |
||||
{ |
||||
public ProfileExecutableForm() |
||||
{ |
||||
InitializeComponent(); |
||||
} |
||||
|
||||
void btnCancelClick(object sender, RoutedEventArgs e) |
||||
{ |
||||
this.Close(); |
||||
} |
||||
|
||||
void btnStartClick(object sender, RoutedEventArgs e) |
||||
{ |
||||
try { |
||||
if (!File.Exists(txtExePath.Text)) |
||||
throw new FileNotFoundException("file '" + txtExePath.Text + "' was not found!"); |
||||
if (!Directory.Exists(txtWorkingDir.Text)) |
||||
throw new DirectoryNotFoundException("directory '" + txtWorkingDir.Text + "' was not found!"); |
||||
|
||||
string outputPath = Path.Combine( |
||||
Path.GetDirectoryName(txtExePath.Text), |
||||
@"ProfilingSessions\Session" + |
||||
DateTime.Now.ToString("yyyyMMdd_HHmmss", CultureInfo.InvariantCulture) + ".sdps"); |
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); |
||||
|
||||
var runner = CreateRunner(txtExePath.Text, txtWorkingDir.Text, txtArgs.Text, new ProfilingDataSQLiteWriter(outputPath)); |
||||
|
||||
if (runner != null) { |
||||
runner.RunFinished += delegate { |
||||
string title = Path.GetFileName(outputPath); |
||||
ProfilingDataProvider provider = new ProfilingDataSQLiteProvider(outputPath); |
||||
WorkbenchSingleton.CallLater(20, () => WorkbenchSingleton.Workbench.ShowView(new WpfViewer(provider, title))); |
||||
}; |
||||
|
||||
runner.Run(); |
||||
} |
||||
|
||||
this.Close(); |
||||
} catch (ArgumentNullException) { |
||||
MessageService.ShowError("Invalid data, please try again!"); |
||||
} catch (FileNotFoundException ex) { |
||||
MessageService.ShowError(ex.Message); |
||||
} catch (DirectoryNotFoundException ex2) { |
||||
MessageService.ShowError(ex2.Message); |
||||
} catch (Exception ex3) { |
||||
MessageService.ShowError(ex3); |
||||
} |
||||
} |
||||
|
||||
void btnSelectFileClick(object sender, RoutedEventArgs e) |
||||
{ |
||||
var dlg = new OpenFileDialog(); |
||||
dlg.Filter = "Programs|*.exe|All files|*.*"; |
||||
dlg.DefaultExt = ".exe"; |
||||
if (!(dlg.ShowDialog() ?? false)) |
||||
return; |
||||
txtExePath.Text = dlg.FileName; |
||||
|
||||
if (File.Exists(dlg.FileName)) |
||||
txtWorkingDir.Text = Path.GetDirectoryName(dlg.FileName); |
||||
} |
||||
|
||||
void btnSelectDirClick(object sender, RoutedEventArgs e) |
||||
{ |
||||
var dlg = new System.Windows.Forms.FolderBrowserDialog(); |
||||
|
||||
if (!(dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)) |
||||
return; |
||||
txtWorkingDir.Text = dlg.SelectedPath; |
||||
} |
||||
|
||||
ProfilerRunner CreateRunner(string path, string workingDirectory, string args, IProfilingDataWriter writer) |
||||
{ |
||||
if (args == null) |
||||
throw new ArgumentNullException("args"); |
||||
if (workingDirectory == null) |
||||
throw new ArgumentNullException("workingdirectory"); |
||||
if (path == null) |
||||
throw new ArgumentNullException("path"); |
||||
|
||||
if (!File.Exists(path)) |
||||
throw new FileNotFoundException("file '" + path + "' was not found!"); |
||||
if (!Directory.Exists(workingDirectory)) |
||||
throw new DirectoryNotFoundException("directory '" + workingDirectory + "' was not found!"); |
||||
|
||||
ProcessStartInfo info = new ProcessStartInfo(path, args); |
||||
info.WorkingDirectory = workingDirectory; |
||||
|
||||
ProfilerRunner runner = new ProfilerRunner(info, true, writer); |
||||
|
||||
return runner; |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,121 @@
@@ -0,0 +1,121 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using ICSharpCode.Core; |
||||
using System; |
||||
using System.Diagnostics; |
||||
using ICSharpCode.Profiler.AddIn.OptionsPanels; |
||||
using ICSharpCode.Profiler.Controller.Data; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
|
||||
namespace ICSharpCode.Profiler.AddIn |
||||
{ |
||||
/// <summary>
|
||||
/// Description of ProfilerRunner.
|
||||
/// </summary>
|
||||
public class ProfilerRunner |
||||
{ |
||||
public event EventHandler RunFinished; |
||||
|
||||
protected virtual void OnRunFinished(EventArgs e) |
||||
{ |
||||
if (RunFinished != null) { |
||||
RunFinished(this, e); |
||||
} |
||||
} |
||||
|
||||
Controller.Profiler profiler; |
||||
IProfilingDataWriter writer; |
||||
TempFileDatabase database; |
||||
|
||||
public ICSharpCode.Profiler.Controller.Profiler Profiler { |
||||
get { return profiler; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates a new ProfilerRunner using a ProcessStartInfo and a data writer.
|
||||
/// </summary>
|
||||
public ProfilerRunner(ProcessStartInfo startInfo, bool useTempFileDatabase, IProfilingDataWriter writer) |
||||
{ |
||||
if (writer == null) |
||||
throw new ArgumentNullException("writer"); |
||||
if (startInfo == null) |
||||
throw new ArgumentNullException("startInfo"); |
||||
|
||||
if (useTempFileDatabase) { |
||||
this.database = new TempFileDatabase(); |
||||
this.writer = writer; |
||||
this.profiler = new Controller.Profiler(startInfo, this.database.GetWriter()); |
||||
} else { |
||||
this.database = null; |
||||
this.writer = writer; |
||||
this.profiler = new Controller.Profiler(startInfo, writer); |
||||
} |
||||
|
||||
this.profiler.ProfilerOptions = General.CreateProfilerOptions(); |
||||
|
||||
this.profiler.RegisterFailed += delegate { MessageService.ShowError("Could not register the profiler into COM Registry. Cannot start profiling!"); }; |
||||
this.profiler.DeregisterFailed += delegate { MessageService.ShowError("Could not unregister the profiler from COM Registry!"); }; |
||||
this.profiler.OutputUpdated += delegate { SetOutputText(profiler.ProfilerOutput); }; |
||||
this.profiler.SessionEnded += delegate { FinishSession(); }; |
||||
} |
||||
|
||||
void FinishSession() |
||||
{ |
||||
profiler.DataWriter.Close(); |
||||
|
||||
if (database != null) { |
||||
database.WriteTo(writer, progress => true); // TODO : change default impl to good user interface notification
|
||||
writer.Close(); |
||||
database.Close(); |
||||
} else { |
||||
writer.Close(); |
||||
} |
||||
|
||||
OnRunFinished(EventArgs.Empty); |
||||
} |
||||
|
||||
public void Run() |
||||
{ |
||||
profiler.Start(); |
||||
} |
||||
|
||||
public void Stop() |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
#region MessageView Management
|
||||
static MessageViewCategory profileCategory = null; |
||||
|
||||
static void EnsureProfileCategory() |
||||
{ |
||||
if (profileCategory == null) { |
||||
MessageViewCategory.Create(ref profileCategory, "Profile", "Profile"); |
||||
} |
||||
} |
||||
|
||||
public static void SetOutputText(string text) |
||||
{ |
||||
EnsureProfileCategory(); |
||||
profileCategory.SetText(text); |
||||
} |
||||
|
||||
public static void AppendOutputText(string text) |
||||
{ |
||||
EnsureProfileCategory(); |
||||
profileCategory.AppendText(text); |
||||
} |
||||
|
||||
public static void AppendOutputLine(string text) |
||||
{ |
||||
EnsureProfileCategory(); |
||||
profileCategory.AppendLine(text); |
||||
} |
||||
#endregion
|
||||
} |
||||
} |
@ -1,91 +0,0 @@
@@ -1,91 +0,0 @@
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using System.Globalization; |
||||
using System.IO; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.Profiler.AddIn.OptionsPanels; |
||||
using ICSharpCode.Profiler.Controller; |
||||
using ICSharpCode.Profiler.Controller.Data; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.Profiler.AddIn |
||||
{ |
||||
/// <summary>
|
||||
/// Provides methods for initialisation and control of the current profiling session.
|
||||
/// </summary>
|
||||
public static class ProfilerService |
||||
{ |
||||
public static Profiler.Controller.Profiler RunCurrentProject(out string profilerSessionFilePath) |
||||
{ |
||||
AbstractProject currentProj = ProjectService.CurrentProject as AbstractProject; |
||||
|
||||
profilerSessionFilePath = Path.Combine(currentProj.Directory, @"ProfilingSessions\Session" + DateTime.Now.ToString("yyyyMMdd_HHmmss", CultureInfo.InvariantCulture) + ".sdps"); |
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(profilerSessionFilePath)); |
||||
|
||||
if (currentProj == null) |
||||
return null; |
||||
|
||||
if (!currentProj.IsStartable) { |
||||
MessageService.ShowError("This project cannot be started, please select a startable project for Profiling!"); |
||||
return null; |
||||
} |
||||
if (!File.Exists(currentProj.OutputAssemblyFullPath)) { |
||||
MessageService.ShowError("This project cannot be started because the executable file was not found, " + |
||||
"please ensure that the project and all its depencies are built correctly!"); |
||||
return null; |
||||
} |
||||
|
||||
Profiler.Controller.Profiler profiler = InitProfiler(currentProj.CreateStartInfo(), profilerSessionFilePath); |
||||
profiler.ProfilerOptions = General.CreateProfilerOptions(); |
||||
profiler.Start(); |
||||
|
||||
return profiler; |
||||
} |
||||
|
||||
static Profiler.Controller.Profiler InitProfiler(string path, string outputFilePath) |
||||
{ |
||||
return InitProfiler(new ProcessStartInfo(path), outputFilePath); |
||||
} |
||||
|
||||
static Profiler.Controller.Profiler InitProfiler(ProcessStartInfo startInfo, string outputFilePath) |
||||
{ |
||||
Profiler.Controller.Profiler profiler = new Profiler.Controller.Profiler(startInfo, new ProfilingDataSQLiteWriter(outputFilePath)); |
||||
|
||||
profiler.RegisterFailed += delegate { MessageService.ShowError("Could not register the profiler into COM Registry. Cannot start profiling!"); }; |
||||
profiler.DeregisterFailed += delegate { MessageService.ShowError("Could not unregister the profiler from COM Registry!"); }; |
||||
profiler.OutputUpdated += delegate { SetOutputText(profiler.ProfilerOutput); }; |
||||
|
||||
return profiler; |
||||
} |
||||
|
||||
static MessageViewCategory profileCategory = null; |
||||
|
||||
static void EnsureProfileCategory() |
||||
{ |
||||
if (profileCategory == null) { |
||||
MessageViewCategory.Create(ref profileCategory, "Profile", "Profile"); |
||||
} |
||||
} |
||||
|
||||
public static void SetOutputText(string text) |
||||
{ |
||||
EnsureProfileCategory(); |
||||
profileCategory.SetText(text); |
||||
} |
||||
|
||||
public static void AppendOutputText(string text) |
||||
{ |
||||
EnsureProfileCategory(); |
||||
profileCategory.AppendText(text); |
||||
} |
||||
|
||||
public static void AppendOutputLine(string text) |
||||
{ |
||||
EnsureProfileCategory(); |
||||
profileCategory.AppendLine(text); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue