logic: fix more Visual Studio plugin issues
* using .Net framework version 4.6.1 in all projects * implemented exception handling in VCFileWrapperFactory * moved logging in separate assembly * enabled logging in wrapper code
This commit is contained in:
Binary file not shown.
+67
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Logging
|
||||
{
|
||||
public class FileLogger : ILogger
|
||||
{
|
||||
private static string _directory = "";
|
||||
private static string _fileNamePrefix = "Log_SourcetrailPlugin_";
|
||||
private static string _fileNameSufix = ".txt";
|
||||
|
||||
private string _fileName = "";
|
||||
|
||||
private Queue<string> _messageBacklog = new Queue<string>(); // stores messages if the log file was in use at original logging time
|
||||
|
||||
public FileLogger()
|
||||
{
|
||||
DateTime time = DateTime.Now;
|
||||
|
||||
string dateString = "";
|
||||
dateString += time.Year.ToString() + "-" + time.Month.ToString() + "-" + time.Day.ToString() + "_";
|
||||
dateString += time.Hour.ToString() + "-" + time.Minute.ToString() + "-" + time.Second.ToString();
|
||||
|
||||
_fileName = _fileNamePrefix + dateString + _fileNameSufix;
|
||||
|
||||
_directory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
_directory += "\\Coati Software\\Plugins\\VS\\";
|
||||
|
||||
if(System.IO.Directory.Exists(_directory) == false)
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(_directory);
|
||||
}
|
||||
}
|
||||
|
||||
public void LogMessage(LogMessage message)
|
||||
{
|
||||
System.IO.StreamWriter writer = null;
|
||||
|
||||
try
|
||||
{
|
||||
writer = System.IO.File.AppendText(_directory + _fileName);
|
||||
|
||||
// write backlog to file first
|
||||
while(_messageBacklog.Count > 0)
|
||||
{
|
||||
string bm = _messageBacklog.Dequeue();
|
||||
writer.WriteLine(bm);
|
||||
}
|
||||
|
||||
writer.WriteLine(message.ToString());
|
||||
writer.Close();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// well...file is still in use
|
||||
_messageBacklog.Enqueue(message.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if(writer != null)
|
||||
{
|
||||
writer.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Logging
|
||||
{
|
||||
public interface ILogger
|
||||
{
|
||||
void LogMessage(LogMessage message);
|
||||
}
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Logging
|
||||
{
|
||||
public class LogManager
|
||||
{
|
||||
private static LogManager _instance = null;
|
||||
|
||||
private List<ILogger> _loggers = new List<ILogger>();
|
||||
|
||||
private bool _loggingEnabled = false;
|
||||
|
||||
public List<ILogger> Loggers
|
||||
{
|
||||
get { return _loggers; }
|
||||
set { _loggers = value; }
|
||||
}
|
||||
|
||||
public bool LoggingEnabled
|
||||
{
|
||||
get { return _loggingEnabled; }
|
||||
set { _loggingEnabled = value; }
|
||||
}
|
||||
|
||||
private LogManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static LogManager GetInstance()
|
||||
{
|
||||
if(_instance == null)
|
||||
{
|
||||
_instance = new LogManager();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public void LogInfo(string message, string sourceFile, string callingFunction, int lineNumber)
|
||||
{
|
||||
LogMessage logMessage = new LogMessage();
|
||||
logMessage.Message = message;
|
||||
logMessage.MessageType = LogMessage.LogMessageType.INFO;
|
||||
logMessage.Time = DateTime.Now;
|
||||
logMessage.SourceFile = sourceFile;
|
||||
logMessage.CallingFunction = callingFunction;
|
||||
logMessage.LineNumber = lineNumber;
|
||||
|
||||
Log(logMessage);
|
||||
}
|
||||
|
||||
public void LogWarning(string message, string sourceFile, string callingFunction, int lineNumber)
|
||||
{
|
||||
LogMessage logMessage = new LogMessage();
|
||||
logMessage.Message = message;
|
||||
logMessage.MessageType = LogMessage.LogMessageType.WARNING;
|
||||
logMessage.Time = DateTime.Now;
|
||||
logMessage.SourceFile = sourceFile;
|
||||
logMessage.CallingFunction = callingFunction;
|
||||
logMessage.LineNumber = lineNumber;
|
||||
|
||||
Log(logMessage);
|
||||
}
|
||||
|
||||
public void LogError(string message, string sourceFile, string callingFunction, int lineNumber)
|
||||
{
|
||||
LogMessage logMessage = new LogMessage();
|
||||
logMessage.Message = message;
|
||||
logMessage.MessageType = LogMessage.LogMessageType.ERROR;
|
||||
logMessage.Time = DateTime.Now;
|
||||
logMessage.SourceFile = sourceFile;
|
||||
logMessage.CallingFunction = callingFunction;
|
||||
logMessage.LineNumber = lineNumber;
|
||||
|
||||
Log(logMessage);
|
||||
}
|
||||
|
||||
private void Log(LogMessage message)
|
||||
{
|
||||
if(_loggingEnabled == true)
|
||||
{
|
||||
foreach (ILogger logger in _loggers)
|
||||
{
|
||||
logger.LogMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Logging
|
||||
{
|
||||
public class LogMessage
|
||||
{
|
||||
public enum LogMessageType
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
INFO,
|
||||
WARNING,
|
||||
ERROR
|
||||
}
|
||||
|
||||
private string _message = "";
|
||||
private DateTime _time = new DateTime();
|
||||
private LogMessageType _messageType = LogMessageType.UNKNOWN;
|
||||
|
||||
private string _sourceFile = "";
|
||||
private string _callingFunction = "";
|
||||
private int _lineNumber = -1;
|
||||
|
||||
public string Message
|
||||
{
|
||||
get { return _message; }
|
||||
set { _message = value; }
|
||||
}
|
||||
|
||||
public DateTime Time
|
||||
{
|
||||
get { return _time; }
|
||||
set { _time = value; }
|
||||
}
|
||||
|
||||
public LogMessageType MessageType
|
||||
{
|
||||
get { return _messageType; }
|
||||
set { _messageType = value; }
|
||||
}
|
||||
|
||||
public string SourceFile
|
||||
{
|
||||
get { return _sourceFile; }
|
||||
set { _sourceFile = value; }
|
||||
}
|
||||
|
||||
public string CallingFunction
|
||||
{
|
||||
get { return _callingFunction; }
|
||||
set { _callingFunction = value; }
|
||||
}
|
||||
|
||||
public int LineNumber
|
||||
{
|
||||
get { return _lineNumber; }
|
||||
set { _lineNumber = value; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = "";
|
||||
|
||||
result += _time.Hour.ToString() + ":" + _time.Minute.ToString() + ":"+ _time.Second.ToString();
|
||||
|
||||
result += "\t";
|
||||
|
||||
result += _messageType.ToString();
|
||||
|
||||
result += "\t";
|
||||
|
||||
result += _sourceFile + ":" + _lineNumber.ToString();
|
||||
|
||||
result += " (";
|
||||
|
||||
result += _callingFunction;
|
||||
|
||||
result += ")";
|
||||
|
||||
result += "\t\t";
|
||||
|
||||
result += _message;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Logging
|
||||
{
|
||||
public class Logging
|
||||
{
|
||||
public static void LogInfo(string message, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0)
|
||||
{
|
||||
int idx = file.LastIndexOf('\\');
|
||||
if(idx > -1)
|
||||
{
|
||||
file = file.Substring(idx + 1);
|
||||
}
|
||||
|
||||
LogManager.GetInstance().LogInfo(message, file, member, line);
|
||||
}
|
||||
|
||||
public static void LogWarning(string message, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0)
|
||||
{
|
||||
int idx = file.LastIndexOf('\\');
|
||||
if (idx > -1)
|
||||
{
|
||||
file = file.Substring(idx + 1);
|
||||
}
|
||||
|
||||
LogManager.GetInstance().LogWarning(message, file, member, line);
|
||||
}
|
||||
|
||||
public static void LogError(string message, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0)
|
||||
{
|
||||
int idx = file.LastIndexOf('\\');
|
||||
if (idx > -1)
|
||||
{
|
||||
file = file.Substring(idx + 1);
|
||||
}
|
||||
|
||||
LogManager.GetInstance().LogError(message, file, member, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Logging.Obfuscation
|
||||
{
|
||||
public class NameObfuscator
|
||||
{
|
||||
private static NameObfuscator _instance = null;
|
||||
|
||||
private Dictionary<string, string> _dictionary = new Dictionary<string, string>();
|
||||
private bool _enabled = false;
|
||||
|
||||
char _currentChar = 'a';
|
||||
int _currentInt = 0;
|
||||
|
||||
private static string _directory = "";
|
||||
private static string _fileNamePrefix = "Dictionary_SourcetrailPlugin_";
|
||||
private static string _fileNameSufix = ".txt";
|
||||
|
||||
private string _fileName = "";
|
||||
|
||||
private Queue<string> _messageBacklog = new Queue<string>(); // stores messages if the log file was in use at original logging time
|
||||
|
||||
private NameObfuscator()
|
||||
{
|
||||
DateTime time = DateTime.Now;
|
||||
|
||||
string dateString = "";
|
||||
dateString += time.Year.ToString() + "-" + time.Month.ToString() + "-" + time.Day.ToString() + "_";
|
||||
dateString += time.Hour.ToString() + "-" + time.Minute.ToString() + "-" + time.Second.ToString();
|
||||
|
||||
_fileName = _fileNamePrefix + dateString + _fileNameSufix;
|
||||
|
||||
_directory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
_directory += "\\Coati Software\\Plugins\\VS\\";
|
||||
|
||||
if (System.IO.Directory.Exists(_directory) == false)
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(_directory);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreateInstance()
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new NameObfuscator();
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetObfuscatedName(string originalName)
|
||||
{
|
||||
CreateInstance();
|
||||
|
||||
if (_instance._enabled)
|
||||
{
|
||||
if (_instance._dictionary.ContainsKey(originalName))
|
||||
{
|
||||
return _instance._dictionary[originalName];
|
||||
}
|
||||
else
|
||||
{
|
||||
string newName = _instance.GetNewName();
|
||||
_instance._dictionary[originalName] = newName;
|
||||
|
||||
_instance.WriteDictionaryEntryToFile(newName, originalName); // key and value reversed because that's the way the dictionary file is to be used...
|
||||
return newName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return originalName;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Enabled(bool enabled)
|
||||
{
|
||||
CreateInstance();
|
||||
|
||||
_instance._enabled = enabled;
|
||||
}
|
||||
|
||||
private string GetNewName()
|
||||
{
|
||||
string name = "";
|
||||
|
||||
name = _currentChar.ToString() + _currentInt.ToString();
|
||||
|
||||
++_currentChar;
|
||||
|
||||
if((int)_currentChar > 122)
|
||||
{
|
||||
_currentChar = 'a';
|
||||
++_currentInt;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
private void WriteDictionaryEntryToFile(string key, string value)
|
||||
{
|
||||
System.IO.StreamWriter writer = null;
|
||||
string message = key + " - " + value;
|
||||
|
||||
try
|
||||
{
|
||||
writer = System.IO.File.AppendText(_directory + _fileName);
|
||||
|
||||
// write backlog to file first
|
||||
while (_messageBacklog.Count > 0)
|
||||
{
|
||||
string bm = _messageBacklog.Dequeue();
|
||||
writer.WriteLine(bm);
|
||||
}
|
||||
|
||||
writer.WriteLine(message.ToString());
|
||||
writer.Close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// well...file is still in use
|
||||
_messageBacklog.Enqueue(message.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (writer != null)
|
||||
{
|
||||
writer.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
using EnvDTE;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Logging
|
||||
{
|
||||
public class VSOutputLogger : ILogger
|
||||
{
|
||||
private EnvDTE.DTE _dte = null;
|
||||
private OutputWindowPane _pane = null;
|
||||
|
||||
public VSOutputLogger(EnvDTE.DTE dte)
|
||||
{
|
||||
_dte = dte;
|
||||
}
|
||||
|
||||
public void LogMessage(LogMessage message)
|
||||
{
|
||||
if (message.MessageType == SourcetrailPlugin.Logging.LogMessage.LogMessageType.INFO)
|
||||
{
|
||||
Debug.WriteLine(message.Message, "Info");
|
||||
WriteToOutputWindow("Info: " + message.Message);
|
||||
}
|
||||
if (message.MessageType == SourcetrailPlugin.Logging.LogMessage.LogMessageType.WARNING)
|
||||
{
|
||||
Debug.WriteLine(message.Message, "Warning");
|
||||
WriteToOutputWindow("Warning: " + message.Message);
|
||||
}
|
||||
if (message.MessageType == SourcetrailPlugin.Logging.LogMessage.LogMessageType.ERROR)
|
||||
{
|
||||
Debug.WriteLine(message.Message, "Error");
|
||||
WriteToOutputWindow("Error: " + message.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteToOutputWindow(string message)
|
||||
{
|
||||
string paneName = "Sourcetrail Log";
|
||||
|
||||
if (_dte.Windows.Count > 0)
|
||||
{
|
||||
Window window = _dte.Windows.Item(EnvDTE.Constants.vsWindowKindOutput);
|
||||
OutputWindow outputWindow = (OutputWindow)window.Object;
|
||||
|
||||
OutputWindowPanes panes = outputWindow.OutputWindowPanes;
|
||||
|
||||
if(_pane == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < panes.Count; i++)
|
||||
{
|
||||
OutputWindowPane pane = panes.Item(i);
|
||||
|
||||
if (pane.Name.Equals(paneName, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
_pane = outputWindow.OutputWindowPanes.Item(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (_pane == null)
|
||||
{
|
||||
_pane = outputWindow.OutputWindowPanes.Add(paneName);
|
||||
}
|
||||
|
||||
_pane.OutputString(message + '\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("SourcetrailPluginUtility")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Coati Software")]
|
||||
[assembly: AssemblyProduct("SourcetrailPluginUtility")]
|
||||
[assembly: AssemblyCopyright("Copyright © Coati Software 2017")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("604b5751-af34-4ff9-92c3-c85a6bcdf98e")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.*")]
|
||||
//[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{604B5751-AF34-4FF9-92C3-C85A6BCDF98E}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>CoatiSoftware.SourcetrailPlugin</RootNamespace>
|
||||
<AssemblyName>SourcetrailPluginUtility</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<EmbedInteropTypes>False</EmbedInteropTypes>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.11.0, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Logging\FileLogger.cs" />
|
||||
<Compile Include="Logging\ILogger.cs" />
|
||||
<Compile Include="Logging\Logging.cs" />
|
||||
<Compile Include="Logging\LogManager.cs" />
|
||||
<Compile Include="Logging\LogMessage.cs" />
|
||||
<Compile Include="Logging\Obfuscation\NameObfuscator.cs" />
|
||||
<Compile Include="Logging\VSOutputLogger.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Key.snk" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
Reference in New Issue
Block a user