Example #1
0
        private void ImportJson(string json)
        {
            if (string.IsNullOrWhiteSpace(json))
            {
                FlexibleMessageBox.Show("No JSON data.", "Import Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            Dictionary <string, string> importedSnippets;

            try
            {
                importedSnippets = JsonSerializer.Deserialize <Dictionary <string, string> >(json);
            }
            catch
            {
                FlexibleMessageBox.Show("Invalid JSON data.", "Import Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (importedSnippets == null || importedSnippets.Count == 0)
            {
                FlexibleMessageBox.Show("No JSON data.", "Import Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            int importCount = 0;

            foreach (KeyValuePair <string, string> kvp in importedSnippets)
            {
                if (IsValidSnippetName(kvp.Key) && !Intelli.Snippets.ContainsKey(kvp.Key))
                {
                    Intelli.Snippets.Add(kvp.Key, kvp.Value);
                    importCount++;
                }
            }

            if (importCount > 0)
            {
                SaveSnippets();
                this.SnippetList.Items.Clear();
                this.SnippetList.Items.AddRange(Intelli.Snippets.Keys.ToArray());
                this.SnippetList.SelectedIndex = this.SnippetList.Items.Count - 1;
            }

            FlexibleMessageBox.Show($"Imported {importCount} of {importedSnippets.Count} {(importedSnippets.Count == 1 ? "Snippet" : "Snippets")}.", "Import Report", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
Example #2
0
        private void UpdateButton_Click(object sender, EventArgs e)
        {
            if (this.SnippetList.SelectedIndex == -1)
            {
                return;
            }

            string snippetName = this.SnippetName.Text.Trim();

            if (!IsValidSnippetName(snippetName))
            {
                FlexibleMessageBox.Show("Invalid Snippet Name.", "Snippet Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            string snippetBody = this.SnippetBody.Text;

            if (string.IsNullOrWhiteSpace(snippetBody))
            {
                FlexibleMessageBox.Show("Snippet Body is empty.", "Snippet Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            System.Diagnostics.Debug.Assert(Intelli.Snippets.ContainsKey(this.currentSnippet));

            if (snippetName != this.currentSnippet && Intelli.Snippets.ContainsKey(snippetName))
            {
                FlexibleMessageBox.Show($"There is already another Snippet with the name of {snippetName}.", "Snippet Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            this.dirty = false;

            Intelli.Snippets.Remove(this.currentSnippet);
            Intelli.Snippets.Add(snippetName, snippetBody);

            SaveSnippets();

            int itemIndex = this.SnippetList.SelectedIndex;

            this.SnippetList.Items.Insert(this.SnippetList.SelectedIndex, snippetName);
            this.SnippetList.Items.RemoveAt(this.SnippetList.SelectedIndex);
            this.SnippetList.SelectedIndex = itemIndex;
        }
Example #3
0
        private string ExportJson()
        {
            if (Intelli.Snippets.Count == 0)
            {
                FlexibleMessageBox.Show("No snippets to export.", "Export Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(null);
            }

            JavaScriptSerializer ser = new JavaScriptSerializer();
            string json = null;

            try
            {
                json = ser.Serialize(Intelli.Snippets);
            }
            catch
            {
            }

            return(FormatJson(json));
        }
Example #4
0
        internal static bool Generate(string slnPath, string name, string effectSource, string iconPath)
        {
            string effectName    = Regex.Replace(name, @"[^\w]", "");
            string projectName   = effectName + "Effect";
            string slnGuid       = "{" + Guid.NewGuid().ToString() + "}";
            string projGroupGuid = "{" + Guid.NewGuid().ToString() + "}";
            string projGuid      = "{" + Guid.NewGuid().ToString() + "}";
            string pdnPath       = Application.StartupPath;
            string projPath      = Path.Combine(slnPath, projectName);
            bool   iconExists    = File.Exists(iconPath);
            string samplePath    = Path.ChangeExtension(iconPath, ".sample.png");
            bool   sampleExists  = File.Exists(samplePath);
            string rtfPath       = Path.ChangeExtension(iconPath, ".rtz");
            bool   rtfExists     = File.Exists(rtfPath);

            // Tab indent
            StringBuilder slnFile = new StringBuilder();

            slnFile.AppendLine();
            slnFile.AppendLine("Microsoft Visual Studio Solution File, Format Version 12.00");
            slnFile.AppendLine("# Visual Studio 15");
            slnFile.AppendLine("VisualStudioVersion = 15.0.28010.0");
            slnFile.AppendLine("MinimumVisualStudioVersion = 10.0.40219.1");
            slnFile.AppendLine($"Project(\"{projGroupGuid}\") = \"{projectName}\", \"{projectName}\\{projectName}.csproj\", \"{projGuid}\"");
            slnFile.AppendLine("EndProject");
            slnFile.AppendLine("Global");
            slnFile.AppendLine("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution");
            slnFile.AppendLine("\t\tDebug|Any CPU = Debug|Any CPU");
            slnFile.AppendLine("\t\tRelease|Any CPU = Release|Any CPU");
            slnFile.AppendLine("\tEndGlobalSection");
            slnFile.AppendLine("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution");
            slnFile.AppendLine($"\t\t{projGuid}.Debug|Any CPU.ActiveCfg = Debug|Any CPU");
            slnFile.AppendLine($"\t\t{projGuid}.Debug|Any CPU.Build.0 = Debug|Any CPU");
            slnFile.AppendLine($"\t\t{projGuid}.Release|Any CPU.ActiveCfg = Release|Any CPU");
            slnFile.AppendLine($"\t\t{projGuid}.Release|Any CPU.Build.0 = Release|Any CPU");
            slnFile.AppendLine("\tEndGlobalSection");
            slnFile.AppendLine("\tGlobalSection(SolutionProperties) = preSolution");
            slnFile.AppendLine("\t\tHideSolutionNode = FALSE");
            slnFile.AppendLine("\tEndGlobalSection");
            slnFile.AppendLine("\tGlobalSection(ExtensibilityGlobals) = postSolution");
            slnFile.AppendLine($"\t\tSolutionGuid = {slnGuid}");
            slnFile.AppendLine("\tEndGlobalSection");
            slnFile.AppendLine("EndGlobal");

            // Two space indent
            StringBuilder csprojFile = new StringBuilder();

            csprojFile.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            csprojFile.AppendLine("<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">");
            csprojFile.AppendLine("  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />");
            csprojFile.AppendLine("  <PropertyGroup>");
            csprojFile.AppendLine("    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>");
            csprojFile.AppendLine("    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>");
            csprojFile.AppendLine($"    <ProjectGuid>{projGuid}</ProjectGuid>");
            csprojFile.AppendLine("    <OutputType>Library</OutputType>");
            csprojFile.AppendLine("    <AppDesignerFolder>Properties</AppDesignerFolder>");
            csprojFile.AppendLine($"    <RootNamespace>{projectName}</RootNamespace>");
            csprojFile.AppendLine($"    <AssemblyName>{effectName}</AssemblyName>");
            csprojFile.AppendLine("    <TargetFrameworkVersion>v4.7</TargetFrameworkVersion>");
            csprojFile.AppendLine("    <FileAlignment>512</FileAlignment>");
            csprojFile.AppendLine("  </PropertyGroup>");
            csprojFile.AppendLine("  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">");
            csprojFile.AppendLine("    <DebugSymbols>true</DebugSymbols>");
            csprojFile.AppendLine("    <DebugType>full</DebugType>");
            csprojFile.AppendLine("    <Optimize>false</Optimize>");
            csprojFile.AppendLine("    <OutputPath>bin\\Debug\\</OutputPath>");
            csprojFile.AppendLine("    <DefineConstants>DEBUG;TRACE</DefineConstants>");
            csprojFile.AppendLine("    <ErrorReport>prompt</ErrorReport>");
            csprojFile.AppendLine("    <WarningLevel>4</WarningLevel>");
            csprojFile.AppendLine("    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>");
            csprojFile.AppendLine("  </PropertyGroup>");
            csprojFile.AppendLine("  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">");
            csprojFile.AppendLine("    <DebugType>pdbonly</DebugType>");
            csprojFile.AppendLine("    <Optimize>true</Optimize>");
            csprojFile.AppendLine("    <OutputPath>bin\\Release\\</OutputPath>");
            csprojFile.AppendLine("    <DefineConstants>TRACE</DefineConstants>");
            csprojFile.AppendLine("    <ErrorReport>prompt</ErrorReport>");
            csprojFile.AppendLine("    <WarningLevel>4</WarningLevel>");
            csprojFile.AppendLine("    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>");
            csprojFile.AppendLine("  </PropertyGroup>");
            csprojFile.AppendLine("  <ItemGroup>");
            csprojFile.AppendLine("    <Reference Include=\"PaintDotNet.Base\">");
            csprojFile.AppendLine($"      <HintPath>{Path.Combine(pdnPath, "PaintDotNet.Base.dll")}</HintPath>");
            csprojFile.AppendLine("    </Reference>");
            csprojFile.AppendLine("    <Reference Include=\"PaintDotNet.Core\">");
            csprojFile.AppendLine($"      <HintPath>{Path.Combine(pdnPath, "PaintDotNet.Core.dll")}</HintPath>");
            csprojFile.AppendLine("    </Reference>");
            csprojFile.AppendLine("    <Reference Include=\"PaintDotNet.Data\">");
            csprojFile.AppendLine($"      <HintPath>{Path.Combine(pdnPath, "PaintDotNet.Data.dll")}</HintPath>");
            csprojFile.AppendLine("    </Reference>");
            csprojFile.AppendLine("    <Reference Include=\"PaintDotNet.Effects\">");
            csprojFile.AppendLine($"      <HintPath>{Path.Combine(pdnPath, "PaintDotNet.Effects.dll")}</HintPath>");
            csprojFile.AppendLine("    </Reference>");
            csprojFile.AppendLine("    <Reference Include=\"System\" />");
            csprojFile.AppendLine("    <Reference Include=\"System.Core\" />");
            csprojFile.AppendLine("    <Reference Include=\"System.Drawing\" />");
            csprojFile.AppendLine("    <Reference Include=\"System.Windows.Forms\" />");
            csprojFile.AppendLine("    <Reference Include=\"System.Xml.Linq\" />");
            csprojFile.AppendLine("    <Reference Include=\"System.Data.DataSetExtensions\" />");
            csprojFile.AppendLine("    <Reference Include=\"Microsoft.CSharp\" />");
            csprojFile.AppendLine("    <Reference Include=\"System.Data\" />");
            csprojFile.AppendLine("    <Reference Include=\"System.Net.Http\" />");
            csprojFile.AppendLine("    <Reference Include=\"System.Xml\" />");
            csprojFile.AppendLine("  </ItemGroup>");
            csprojFile.AppendLine("  <ItemGroup>");
            csprojFile.AppendLine($"    <Compile Include=\"{effectName}.cs\" />");
            csprojFile.AppendLine("  </ItemGroup>");
            if (iconExists || sampleExists || rtfExists)
            {
                csprojFile.AppendLine("  <ItemGroup>");
                if (iconExists)
                {
                    csprojFile.AppendLine($"    <EmbeddedResource Include=\"{effectName}.png\" />");
                }
                if (sampleExists)
                {
                    csprojFile.AppendLine($"    <EmbeddedResource Include=\"{effectName}.sample.png\" />");
                }
                if (rtfExists)
                {
                    csprojFile.AppendLine($"    <EmbeddedResource Include=\"{effectName}.rtz\" />");
                }
                csprojFile.AppendLine("  </ItemGroup>");
            }
            csprojFile.AppendLine("  <ItemGroup>");
            csprojFile.AppendLine("    <Folder Include=\"Properties\\\" />");
            csprojFile.AppendLine("  </ItemGroup>");
            csprojFile.AppendLine("  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />");
            csprojFile.AppendLine("  <PropertyGroup>");
            csprojFile.AppendLine($"    <PostBuildEvent>cmd /c explorer \"$(TargetDir)\" \r\nexit 0</PostBuildEvent>");
            csprojFile.AppendLine("  </PropertyGroup>");
            csprojFile.Append("</Project>"); // no end-of-line at the end of this file

            // Two space indent
            StringBuilder csprojUserFile = new StringBuilder();

            csprojUserFile.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            csprojUserFile.AppendLine("<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">");
            csprojUserFile.AppendLine("  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'\">");
            csprojUserFile.AppendLine("    <StartAction>Program</StartAction>");
            csprojUserFile.AppendLine($"    <StartProgram>{Path.Combine(pdnPath, "PaintDotNet.exe")}</StartProgram>");
            csprojUserFile.AppendLine($"    <StartWorkingDirectory>{pdnPath}\\</StartWorkingDirectory>");
            csprojUserFile.AppendLine("  </PropertyGroup>");
            csprojUserFile.Append("</Project>"); // no end-of-line at the end of this file


            try
            {
                File.WriteAllText(Path.Combine(slnPath, projectName + ".sln"), slnFile.ToString());

                if (!Directory.Exists(projPath))
                {
                    Directory.CreateDirectory(projPath);
                }

                File.WriteAllText(Path.Combine(projPath, projectName + ".csproj"), csprojFile.ToString());
                File.WriteAllText(Path.Combine(projPath, projectName + ".csproj.user"), csprojUserFile.ToString());
                File.WriteAllText(Path.Combine(projPath, effectName + ".cs"), effectSource);

                if (iconExists)
                {
                    File.Copy(iconPath, Path.Combine(projPath, Path.GetFileName(iconPath)), true);
                }
                if (sampleExists)
                {
                    File.Copy(samplePath, Path.Combine(projPath, Path.GetFileName(samplePath)), true);
                }
                if (rtfExists)
                {
                    File.Copy(rtfPath, Path.Combine(projPath, Path.GetFileName(rtfPath)), true);
                }
            }
            catch (Exception ex)
            {
                FlexibleMessageBox.Show("Solution generated failed.\r\n\r\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(false);
            }

            try
            {
                Process.Start("explorer.exe", "/select," + Path.Combine(slnPath, projectName + ".sln"));
            }
            catch
            {
                FlexibleMessageBox.Show("Could not navigate to the generated Solution file.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return(true);
        }
Example #5
0
        internal static void GoCheckForUpdates(bool silentMode, bool force)
        {
            updateURL = string.Empty;
            updateVER = string.Empty;
            needToShowNotification = false;

            if (!force)
            {
                // only check for updates every 7 days
                if (Math.Abs((Settings.LatestUpdateCheck - DateTime.Today).TotalDays) < 7)
                {
                    return; // not time yet
                }
            }

            Random r = new Random(); // defeat any cache by appending a random number to the URL

            WebClient web = new WebClient();

            web.DownloadStringAsync(new Uri(WebUpdateFile + "?r=" + r.Next(int.MaxValue).ToString()));

            web.DownloadStringCompleted += (sender, e) =>
            {
                UpdateStatus updateStatus = UpdateStatus.Unknown;

                if (!e.Cancelled && e.Error == null)
                {
                    Settings.LatestUpdateCheck = DateTime.Now;

                    foreach (string line in e.Result.Split('\n'))
                    {
                        string[] data = line.Split(';');
                        if (data.Length >= 2 && data[0].Trim() == ThisApplication.Trim())
                        {
                            if (data[1].Trim() != ThisVersion.Trim())
                            {
                                updateStatus = UpdateStatus.UpdateAvailable;
                                updateVER    = data[1].Trim();
                                updateURL    = data[2].Trim();
                            }
                            else
                            {
                                updateStatus = UpdateStatus.UpToDate;
                            }

                            break;
                        }
                    }
                }

                if (silentMode)
                {
                    needToShowNotification = updateStatus == UpdateStatus.UpdateAvailable;
                }
                else
                {
                    switch (updateStatus)
                    {
                    case UpdateStatus.Unknown:
                        FlexibleMessageBox.Show("I'm not sure if you are up-to-date.\n\nI was not able to reach the update website.\n\nTry again later.", "CodeLab Updater", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        break;

                    case UpdateStatus.UpToDate:
                        FlexibleMessageBox.Show("You are up-to-date!", "CodeLab Updater", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        break;

                    case UpdateStatus.UpdateAvailable:
                        if (FlexibleMessageBox.Show("An update to CodeLab is available.\n\nWould you like to download CodeLab v" + updateVER + "?\n\n(This will not close your current CodeLab session.)", "CodeLab Updater", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes)
                        {
                            LaunchUrl(updateURL);
                        }
                        break;
                    }
                }
            };
        }
Example #6
0
        internal static string Generate(string slnPath, string name, string effectSource, string iconPath, string resourcePath)
        {
            string effectName    = Regex.Replace(name, @"[^\w]", "");
            string projectName   = effectName + "Effect";
            string slnGuid       = "{" + Guid.NewGuid().ToString() + "}";
            string projGroupGuid = "{" + Guid.NewGuid().ToString() + "}";
            string projGuid      = "{" + Guid.NewGuid().ToString() + "}";
            string pdnPath       = Application.StartupPath;
            string projPath      = Path.Combine(slnPath, projectName);
            string propPath      = Path.Combine(projPath, "Properties");
            bool   iconExists    = File.Exists(iconPath);
            string samplePath    = Path.ChangeExtension(resourcePath, ".sample.png");
            bool   sampleExists  = File.Exists(samplePath);
            string rtfPath       = Path.ChangeExtension(resourcePath, ".rtz");
            bool   rtfExists     = File.Exists(rtfPath);

            // Tab indent
            StringBuilder slnFile = new StringBuilder();

            slnFile.AppendLine();
            slnFile.AppendLine("Microsoft Visual Studio Solution File, Format Version 12.00");
            slnFile.AppendLine("# Visual Studio 16");
            slnFile.AppendLine("VisualStudioVersion = 16.0.31515.178");
            slnFile.AppendLine("MinimumVisualStudioVersion = 10.0.40219.1");
            slnFile.AppendLine($"Project(\"{projGroupGuid}\") = \"{projectName}\", \"{projectName}\\{projectName}.csproj\", \"{projGuid}\"");
            slnFile.AppendLine("EndProject");
            slnFile.AppendLine("Global");
            slnFile.AppendLine("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution");
            slnFile.AppendLine("\t\tDebug|Any CPU = Debug|Any CPU");
            slnFile.AppendLine("\t\tRelease|Any CPU = Release|Any CPU");
            slnFile.AppendLine("\tEndGlobalSection");
            slnFile.AppendLine("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution");
            slnFile.AppendLine($"\t\t{projGuid}.Debug|Any CPU.ActiveCfg = Debug|Any CPU");
            slnFile.AppendLine($"\t\t{projGuid}.Debug|Any CPU.Build.0 = Debug|Any CPU");
            slnFile.AppendLine($"\t\t{projGuid}.Release|Any CPU.ActiveCfg = Release|Any CPU");
            slnFile.AppendLine($"\t\t{projGuid}.Release|Any CPU.Build.0 = Release|Any CPU");
            slnFile.AppendLine("\tEndGlobalSection");
            slnFile.AppendLine("\tGlobalSection(SolutionProperties) = preSolution");
            slnFile.AppendLine("\t\tHideSolutionNode = FALSE");
            slnFile.AppendLine("\tEndGlobalSection");
            slnFile.AppendLine("\tGlobalSection(ExtensibilityGlobals) = postSolution");
            slnFile.AppendLine($"\t\tSolutionGuid = {slnGuid}");
            slnFile.AppendLine("\tEndGlobalSection");
            slnFile.AppendLine("EndGlobal");

            // Two space indent
            StringBuilder csprojFile = new StringBuilder();

            csprojFile.AppendLine("<Project Sdk=\"Microsoft.NET.Sdk\">");
            csprojFile.AppendLine();
            csprojFile.AppendLine("  <PropertyGroup>");
            csprojFile.AppendLine("    <TargetFramework>net6.0-windows</TargetFramework>");
            csprojFile.AppendLine("    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>");
            csprojFile.AppendLine("    <UseWindowsForms>true</UseWindowsForms>");
            csprojFile.AppendLine("    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>");
            csprojFile.AppendLine($"    <RootNamespace>{projectName}</RootNamespace>");
            csprojFile.AppendLine($"    <AssemblyName>{effectName}</AssemblyName>");
            csprojFile.AppendLine("    <Deterministic>false</Deterministic>");
            csprojFile.AppendLine("  </PropertyGroup>");
            csprojFile.AppendLine();
            if (iconExists || sampleExists || rtfExists)
            {
                csprojFile.AppendLine("  <ItemGroup>");
                if (iconExists)
                {
                    csprojFile.AppendLine($"    <EmbeddedResource Include=\"{effectName}.png\" />");
                }
                if (sampleExists)
                {
                    csprojFile.AppendLine($"    <EmbeddedResource Include=\"{effectName}.sample.png\" />");
                }
                if (rtfExists)
                {
                    csprojFile.AppendLine($"    <EmbeddedResource Include=\"{effectName}.rtz\" />");
                }
                csprojFile.AppendLine("  </ItemGroup>");
                csprojFile.AppendLine();
            }
            csprojFile.AppendLine("  <ItemGroup>");
            csprojFile.AppendLine("    <Reference Include=\"PaintDotNet.Base\">");
            csprojFile.AppendLine($"      <HintPath>{Path.Combine(pdnPath, "PaintDotNet.Base.dll")}</HintPath>");
            csprojFile.AppendLine("    </Reference>");
            csprojFile.AppendLine("    <Reference Include=\"PaintDotNet.Core\">");
            csprojFile.AppendLine($"      <HintPath>{Path.Combine(pdnPath, "PaintDotNet.Core.dll")}</HintPath>");
            csprojFile.AppendLine("    </Reference>");
            csprojFile.AppendLine("    <Reference Include=\"PaintDotNet.Data\">");
            csprojFile.AppendLine($"      <HintPath>{Path.Combine(pdnPath, "PaintDotNet.Data.dll")}</HintPath>");
            csprojFile.AppendLine("    </Reference>");
            csprojFile.AppendLine("    <Reference Include=\"PaintDotNet.Effects\">");
            csprojFile.AppendLine($"      <HintPath>{Path.Combine(pdnPath, "PaintDotNet.Effects.dll")}</HintPath>");
            csprojFile.AppendLine("    </Reference>");
            csprojFile.AppendLine("  </ItemGroup>");
            csprojFile.AppendLine();
            csprojFile.AppendLine("  <Target Name=\"PostBuild\" AfterTargets=\"PostBuildEvent\">");
            csprojFile.AppendLine("    <Exec Command=\"cmd /c explorer &quot;$(TargetDir)&quot;&#xD;&#xA;exit 0\" />");
            csprojFile.AppendLine("  </Target>");
            csprojFile.Append("</Project>"); // no end-of-line at the end of this file

            // Two space indent
            StringBuilder launchSettingsFile = new StringBuilder();

            launchSettingsFile.AppendLine("{");
            launchSettingsFile.AppendLine("  \"profiles\": {");
            launchSettingsFile.AppendLine("    \"" + projectName + "\": {");
            launchSettingsFile.AppendLine("      \"commandName\": \"Executable\",");
            launchSettingsFile.AppendLine($"      \"executablePath\": \"{Path.Combine(pdnPath, "PaintDotNet.exe").Replace(@"\", @"\\")}\",");
            launchSettingsFile.AppendLine($"      \"workingDirectory\": \"{pdnPath.Replace(@"\", @"\\")}\"");
            launchSettingsFile.AppendLine("    }");
            launchSettingsFile.AppendLine("  }");
            launchSettingsFile.Append("}"); // no end-of-line at the end of this file

            try
            {
                File.WriteAllText(Path.Combine(slnPath, projectName + ".sln"), slnFile.ToString());

                if (!Directory.Exists(projPath))
                {
                    Directory.CreateDirectory(projPath);
                }

                File.WriteAllText(Path.Combine(projPath, projectName + ".csproj"), csprojFile.ToString());
                File.WriteAllText(Path.Combine(projPath, effectName + ".cs"), effectSource);

                if (iconExists)
                {
                    File.Copy(iconPath, Path.Combine(projPath, Path.GetFileName(iconPath)), true);
                }
                if (sampleExists)
                {
                    File.Copy(samplePath, Path.Combine(projPath, Path.GetFileName(samplePath)), true);
                }
                if (rtfExists)
                {
                    File.Copy(rtfPath, Path.Combine(projPath, Path.GetFileName(rtfPath)), true);
                }

                if (!Directory.Exists(propPath))
                {
                    Directory.CreateDirectory(propPath);
                }

                File.WriteAllText(Path.Combine(propPath, "launchSettings.json"), launchSettingsFile.ToString());
            }
            catch (Exception ex)
            {
                FlexibleMessageBox.Show("Solution generated failed.\r\n\r\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(null);
            }

            return(Path.Combine(slnPath, projectName + ".sln"));
        }