publicclassINIToCSharpCodeGenerator : BaseCodeGeneratorWithSite { publicconststring Name = nameof(INIToCSharpCodeGenerator);
publicconststring Description = "Generates the C# class from INI file";
publicoverridestringGetDefaultExtension() { ThreadHelper.ThrowIfNotOnUIThread(); var item = (ProjectItem)GetService(typeof(ProjectItem)); var ext = Path.GetExtension(item?.FileNames[1]); return$".cs"; }
publicstringPoorManINIToCS(string path) { var lines = File.ReadAllLines( path );
Dictionary<string, Dictionary<string, string>> dict = new Dictionary<string, Dictionary<string, string>>( );
//類別區塊 var classSection = new Regex( @"\[\w+\]" ); //屬性區塊 var propSection = new Regex( @"(?<prop>\w+) (=) (?<val>.*)" ); bool isClass = false;
string holdClass = ""; foreach (var line in lines) { //如果是的話進入到下個階段辨識 isClass = classSection.IsMatch( line ); if (isClass == true) { dict.Add( line, null ); holdClass = line; dict[holdClass] = new Dictionary<string, string>( ); }
//如果完全符合規則取得屬性與數值 var isProp = propSection.IsMatch( line ); if (isProp) { var match = propSection.Match( line ); var prop = match.Groups["prop"].Value; var val = match.Groups["val"].Value; dict[holdClass].Add( prop, val ); } } StringBuilder sb = new StringBuilder( ); foreach (var d in dict) { sb.AppendLine( $@"public class {d.Key.Replace( "[", "" ).Replace( "]", "" )} " ); sb.AppendLine( "{" ); foreach (var item in d.Value) { bool boolVal = false; var isBool = bool.TryParse( item.Value, out boolVal );
int intVal = 0; var isInt = int.TryParse( item.Value, out intVal );
double doubleVal = 0.0; var isDouble = double.TryParse( item.Value, out doubleVal );
protectedoverridebyte[] GenerateCode(string inputFileName, string inputFileContent) { ThreadHelper.ThrowIfNotOnUIThread(); string document = string.Empty; try { document = ThreadHelper.JoinableTaskFactory.Run(async () => { var text = PoorManINIToCS( inputFileName ); //var text = File.ReadAllText(inputFileName); // Alternatively, you can also use inputFileContent directly. //var schema = NJsonSchema.JsonSchema.FromSampleJson(text); //var generator = new CSharpGenerator(schema); returnawait System.Threading.Tasks.Task.FromResult(text); }); } catch (Exception exception) { // Write in output window var outputWindowPane = this.GetService(typeof(SVsGeneralOutputWindowPane)) as IVsOutputWindowPane; if (outputWindowPane != null) { outputWindowPane.OutputString($"An exception occurred while generating code {exception.ToString()}"); }
// Show in error list this.GeneratorErrorCallback(false, 1, $"An exception occurred while generating code {exception.ToString()}", 1, 1); this.ErrorList.ForceShowErrors(); }
///<summary> /// Command menu group (command set GUID). ///</summary> publicstaticreadonly Guid CommandSet = new Guid( "9623d4ed-6401-4963-b5aa-fc850be96b6e" );
///<summary> /// VS Package that provides this command, not null. ///</summary> privatereadonly AsyncPackage package;
var menuCommandID = new CommandID( CommandSet, CommandId ); var menuItem = new MenuCommand( this.Execute, menuCommandID ); commandService.AddCommand( menuItem ); }
///<summary> /// Gets the instance of the command. ///</summary> publicstatic CodeGenCommand Instance { get; privateset; }
///<summary> /// Gets the service provider from the owner package. ///</summary> private Microsoft.VisualStudio.Shell.IAsyncServiceProvider ServiceProvider { get { returnthis.package; } }
///<summary> /// Initializes the singleton instance of the command. ///</summary> ///<param name="package">Owner package, not null.</param> publicstaticasync Task InitializeAsync(AsyncPackage package) { // Switch to the main thread - the call to AddCommand in CodeGenCommand's constructor requires // the UI thread. //await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync( package.DisposalToken );
//OleMenuCommandService commandService = await package.GetServiceAsync( typeof( IMenuCommandService ) ) as OleMenuCommandService; //Instance = new CodeGenCommand( package, commandService );
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken); dte = (DTE)await package.GetServiceAsync(typeof(DTE)); Assumes.Present(dte); IMenuCommandService commandService = await package.GetServiceAsync(typeof(IMenuCommandService)) as IMenuCommandService; Instance = new CodeGenCommand(package, commandService); } privatestatic DTE dte; ///<summary> /// This function is the callback used to execute the command when the menu item is clicked. /// See the constructor to see how the menu item is associated with this function using /// OleMenuCommandService service and MenuCommand class. ///</summary> ///<param name="sender">Event sender.</param> ///<param name="e">Event args.</param> privatevoidExecute(object sender, EventArgs e) { //ThreadHelper.ThrowIfNotOnUIThread( ); //string message = string.Format( CultureInfo.CurrentCulture, "Inside {0}.MenuItemCallback()", this.GetType( ).FullName ); //string title = "CodeGenCommand";
// Show a message box to prove we were here //VsShellUtilities.ShowMessageBox( // this.package, // message, // title, // OLEMSGICON.OLEMSGICON_INFO, // OLEMSGBUTTON.OLEMSGBUTTON_OK, // OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST );
/// <summary> /// Initialization of the package; this method is called right after the package is sited, so this is the place /// where you can put all the initialization code that rely on services provided by VisualStudio. /// </summary> /// <param name="cancellationToken">A cancellation token to monitor for initialization cancellation, which can occur when VS is shutting down.</param> /// <param name="progress">A provider for progress updates.</param> /// <returns>A task representing the async work of package initialization, or an already completed task if there is none. Do not return null from this method.</returns> protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress) { // When initialized asynchronously, the current thread may be a background thread at this point. // Do any initialization that requires the UI thread after switching to the UI thread. await this.JoinableTaskFactory.SwitchToMainThreadAsync( cancellationToken ); await CodeGenCommand.InitializeAsync(this); }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Text.RegularExpressions;
namespace ConvINIToCSharp { class Program { static void Main(string[] args) { PoorManINIToCS( "d:\\test.ini" ); } public static void PoorManINIToCS(string path) { var lines = File.ReadAllLines( path );
Dictionary<string, Dictionary<string, string>> dict = new Dictionary<string, Dictionary<string, string>>( );
//類別區塊 var classSection = new Regex( @"\[\w+\]" ); //屬性區塊 var propSection = new Regex( @"(?<prop>\w+) (=) (?<val>.*)" ); bool isClass = false;
string holdClass = ""; foreach (var line in lines) { //如果是的話進入到下個階段辨識 isClass = classSection.IsMatch( line ); if (isClass == true) { dict.Add( line, null ); holdClass = line; dict[holdClass] = new Dictionary<string, string>( ); }
//如果完全符合規則取得屬性與數值 var isProp = propSection.IsMatch( line ); if (isProp) { var match = propSection.Match( line ); var prop = match.Groups["prop"].Value; var val = match.Groups["val"].Value; dict[holdClass].Add( prop, val ); } }
foreach (var d in dict) { Console.WriteLine( $@"public class {d.Key.Replace( "[", "" ).Replace( "]", "" )} " ); Console.WriteLine( "{" ); foreach (var item in d.Value) { bool boolVal = false; var isBool = bool.TryParse( item.Value, out boolVal );
int intVal = 0; var isInt = int.TryParse( item.Value, out intVal );
double doubleVal = 0.0; var isDouble = double.TryParse( item.Value, out doubleVal );