I'm building a small C# program to collect information on the used nuget packages
This is every piece of info i want:
public class Package
{
public string Version { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int Count { get; set; }
public List<string> Versions { get; set; }
}
And this is how i collect all the info:
public partial class MainWindow : Window
{
public Dictionary<string, Package> Packages;
public string Folder;
public SaveFileDialog saveFileDialog = new SaveFileDialog();
public FolderBrowserDialog folderBrowseDialog = new FolderBrowserDialog();
public MainWindow()
{
InitializeComponent();
Packages = new Dictionary<string, Package>();
}
private void SearchBtn_Click(object sender, RoutedEventArgs e)
{
DialogResult result = folderBrowseDialog.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
DoneLbl.Content = "Started";
Folder = folderBrowseDialog.SelectedPath;
foreach (string fileName in Directory.EnumerateFiles(Folder, "packages.config", SearchOption.AllDirectories))
{
var file = new PackageReferenceFile(fileName);
foreach (PackageReference packageReference in file.GetPackageReferences())
{
if (Packages.ContainsKey(packageReference.Id))
{
Packages[packageReference.Id].Count++;
if (Packages[packageReference.Id].Versions.Contains(packageReference.Version.ToString()))
{
}
else
{
var oldVersion = new Version(Packages[packageReference.Id].Version);
var newVersion = new Version(packageReference.Version.ToString());
if (newVersion > oldVersion)
{
Packages[packageReference.Id].Version = packageReference.Version.ToString();
}
Packages[packageReference.Id].Versions.Add(packageReference.Version.ToString());
}
}
else
{
var package = new Package();
package.Name = packageReference.Id;
package.Count = 1;
package.Version = packageReference.Version.ToString();
package.Versions = new List<string>();
package.Versions.Add(packageReference.Version.ToString());
Packages.Add(packageReference.Id, package);
}
}
DoneLbl.Content = "Done";
}
}
}
private void ExportBtn_Click(object sender, RoutedEventArgs e)
{
saveFileDialog.Filter = "Text File | *.txt";
DialogResult result = saveFileDialog.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
string lines = "Nuget Packages for \r\n" + Folder + "\r\n";
foreach (var Package in Packages)
{
lines += "********************\r\n";
lines += "Name: " + Package.Value.Name + "\r\n";
lines += "Version: " + Package.Value.Version + "\r\n";
lines += "Different Versions: " + Package.Value.Versions.Count + "\r\n";
lines += "Description: " + Package.Value.Description + "\r\n";
lines += "Count: " + Package.Value.Count + "\r\n";
}
StreamWriter file = new StreamWriter(saveFileDialog.FileName);
file.WriteLine(lines);
file.Close();
}
}
}
This gets everything through "Nuget.Core" nuget package.
But i still lack the description. Is there a way to find package description through this nuget package? Or any other way i can use to find package descriptions?
I looked into the Nuget V3 package as described here:
https://learn.microsoft.com/en-us/nuget/api/nuget-api-v3
Using this i made a GetDescription Method
public async void GetDescription(string name, Package package)
{
List<Lazy<INuGetResourceProvider>> providers = new List<Lazy<INuGetResourceProvider>>();
providers.AddRange(Repository.Provider.GetCoreV3()); // Add v3 API support
PackageSource packageSource = new PackageSource("https://api.nuget.org/v3/index.json");
SourceRepository sourceRepository = new SourceRepository(packageSource, providers);
PackageMetadataResource packageMetadataResource = await sourceRepository.GetResourceAsync<PackageMetadataResource>();
IEnumerable<IPackageSearchMetadata> searchMetadata = await packageMetadataResource.GetMetadataAsync(name, true, true, new Logger(), CancellationToken.None);
package.Description = searchMetadata.First().Description;
}
And called it in the code that adds new packages to the list.
{
var package = new Package();
package.Name = packageReference.Id;
package.Count = 1;
GetDescription(packageReference.Id, package);
package.Version = packageReference.Version.ToString();
package.Versions = new List<string>();
package.Versions.Add(packageReference.Version.ToString());
Packages.Add(packageReference.Id, package);
}
I'll later look to get everything trough Nuget V3 but for now everything works as it should.
Related
I wrote a bot in C#, I used Selenium.
Problem: When I start more threads at same time, the bot does the work in the first window. All of the e-mail addresses are being added to the "E-mail" textbox in the same window instead of one e-mail address per window.
But it should look like:
Start function: DivisionStart()
private void DivisionStart() {
foreach(var account in BotConfig.AccountList) {
while (CurrentBotThreads >= BotConfig.MaxLoginsAtSameTime) {
Thread.Sleep(1000);
}
StartedBotThreads++;
CurrentBotThreads++;
int startIndex = (StartedBotThreads * BotConfig.AdsPerAccount + 1) - BotConfig.AdsPerAccount - 1;
int stopIndex = BotConfig.AdsPerAccount * CurrentBotThreads;
if (stopIndex > BotConfig.ProductList.Count) {
stopIndex = BotConfig.ProductList.Count;
}
Debug.Print("Thread: " + StartedBotThreads);
var adList = GetAdListBy(startIndex, stopIndex);
foreach(var ad in adList) {
Debug.Print("Für thread: " + StartedBotThreads + " | Anzeige: " + ad.AdTitle);
}
Debug.Print("Parallel");
var ebayBotThread = new Thread(() => {
var botOptions = new IBotOptionsModel() {
CaptchaSolverApiKey = CaptchaSolverApiKey,
ReCaptchaSiteKey = "6LcZlE0UAAAAAFQKM6e6WA2XynMyr6WFd5z1l1Nr",
StartPageUrl = "https://www.ebay-kleinanzeigen.de/m-einloggen.html?targetUrl=/",
EbayLoginEmail = account.AccountEmail,
EbayLoginPassword = account.AccountPassword,
Ads = adList,
};
var ebayBot = new EbayBot(this, botOptions);
ebayBot.Start(StartedBotThreads);
Thread.Sleep(5000);
});
ebayBotThread.Start();
}
}
The class with function which will be executed in each thread:
using OpenQA.Selenium;
using Selenium.WebDriver.UndetectedChromeDriver;
using System.Diagnostics;
using TwoCaptcha.Captcha;
using System.Drawing;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chrome.ChromeDriverExtensions;
namespace EbayBot
{
class EbayBot
{
public Selenium.Extensions.SlDriver Driver;
private WebDriverHelper DriverHelper;
private Bot Sender;
private bool CaptchaSolved = false;
public IBotOptionsModel Options;
public EbayBot(Bot sender, IBotOptionsModel options)
{
Sender = sender;
Options = options;
}
public void Start(int threadIndex)
{
var chromeOptions = new ChromeOptions();
/*if (Sender.BotConfig.EnableProxy)
{
chromeOptions.AddHttpProxy(
Options.Proxy.IpAddress,
Options.Proxy.Port,
Options.Proxy.Username,
Options.Proxy.Password
);
}*/
Driver = UndetectedChromeDriver.Instance(null, chromeOptions);
DriverHelper = new WebDriverHelper(Driver);
string status = "";
Debug.Print("Bot-Thread: " + threadIndex);
Driver.Url = Options.StartPageUrl + Options.EbayLoginEmail;
PressAcceptCookiesButton();
Login();
if (!CaptchaSolved) return;
Driver.Wait(3);
if (LoginError() || !IsLoggedIn())
{
status = "Login für '" + Options.EbayLoginEmail + "' fehlgeschlagen!";
Debug.Print(status);
Sender.ProcessStatus = new IStatusModel(status, Color.Red);
return;
}
else
{
status = "Login für '" + Options.EbayLoginEmail + "' war erfolgreich!";
Debug.Print(status);
Sender.ProcessStatus = new IStatusModel(status, Color.Green);
}
Driver.Wait(5);
BeginFillFormular();
}
private bool CookiesAccepted()
{
try
{
var btnAcceptCookies = Driver.FindElement(By.Id(Config.PageElements["id_banner"]));
return btnAcceptCookies == null;
}
catch (Exception)
{
return true;
}
}
private void PressAcceptCookiesButton()
{
DriverHelper.WaitForElement(Config.PageElements["id_banner"], "", 10);
if (CookiesAccepted()) return;
var btnAcceptCookies = Driver.FindElement(By.Id(Config.PageElements["id_banner"]));
btnAcceptCookies.Click();
}
private bool IsLoggedIn()
{
Debug.Print("Check if logged in already");
try
{
var userEmail = Driver.FindElement(By.Id("user-email")).Text;
return userEmail.ToLower().Contains(Options.EbayLoginEmail);
}
catch (Exception)
{
return false;
}
}
private bool LoginError()
{
try
{
var loginErrorH1 = Driver.FindElements(By.TagName("h1"));
return loginErrorH1[0].Text.Contains("ungültig");
}
catch (Exception)
{
return false;
}
}
private void Login()
{
if (IsLoggedIn()) return;
string status = "Anmelden bei " + Options.EbayLoginEmail + "...";
Debug.Print(status);
Sender.ProcessStatus = Sender.ProcessStatus = new IStatusModel(status, Color.DimGray);
Driver.Wait(5);
var fieldEmail = Driver.FindElement(By.Id(Config.PageElements["id_login_email"]));
var fieldPassword = Driver.FindElement(By.Id(Config.PageElements["id_login_password"]));
var btnLoginSubmit = Driver.FindElement(By.Id(Config.PageElements["id_login_button"]));
fieldEmail.SendKeys(Options.EbayLoginEmail);
Driver.Wait(4);
fieldPassword.SendKeys(Options.EbayLoginPassword);
SolveCaptcha();
if (!CaptchaSolved)
{
return;
}
Debug.Print("Clicking login button");
btnLoginSubmit.Click();
}
public void BeginFillFormular()
{
Debug.Print("Formular setup, Inserate: " + Options.Ads.Count);
foreach (var adData in Options.Ads)
{
Debug.Print("Setting up formular for " + adData.AdTitle);
var adFormular = new AdFormular(Driver, adData, Options);
adFormular._EbayBot = this;
adFormular.CreateAd(Sender);
// 10 seconds
Debug.Print("Nächstes Insert für " + adData.AdTitle);
}
}
public string GetSolvedCaptchaAnswer(string captchaUrl = "")
{
string code = string.Empty;
var solver = new TwoCaptcha.TwoCaptcha(Options.CaptchaSolverApiKey);
var captcha = new ReCaptcha();
captcha.SetSiteKey(Options.ReCaptchaSiteKey);
captcha.SetUrl(captchaUrl == "" ? Options.StartPageUrl : captchaUrl);
try
{
solver.Solve(captcha).Wait();
code = captcha.Code;
}
catch (AggregateException e)
{
Sender.ProcessStatus = new IStatusModel("Captcha Api-Fehler: " + e.InnerExceptions.First().Message, Color.Red);
Driver.Wait(10);
}
return code;
}
public void SolveCaptcha(string captchaUrl = "")
{
Debug.Print("Solving captcha...");
var solvedCaptchaAnswer = GetSolvedCaptchaAnswer(captchaUrl);
if (solvedCaptchaAnswer == string.Empty)
{
Debug.Print("Captcha konnte nicht gelöst werden");
Sender.ProcessStatus = new IStatusModel("Captcha konnte nicht gelöst werden", Color.Red);
CaptchaSolved = false;
Driver.Wait(10);
return;
}
CaptchaSolved = true;
Debug.Print("Captcha answer: " + solvedCaptchaAnswer);
Driver.ExecuteScript("document.getElementById('g-recaptcha-response').innerHTML = '" + solvedCaptchaAnswer + "'");
Debug.Print("Captcha solved!");
Driver.Wait(2);
}
}
}
If I remove the Thread.Sleep(5000); in the DivisionStart function it will work, but I need it I actually want to wait for a found proxy but I simulated it with Thread.Sleep
How can I solve my problem?
Thanks for any answer!
I fixed it.
I used UndetectedChromeDriver wich does not use different ports.
I use another Undetected driver now.
Thank you all
I'm having trouble using multiple DotNetBrowser IEngine instances at once.
Whenever I try to use more than one at a time, they conflict, even though I have already defined different folders for each one.
Follow the code I'm using.
public void initializeBrowser(string guid)
{
string contextDirectory = Application.StartupPath + #"\cache\" + guid;
string pathProxy = ConfigurationManager.AppSettings["pathProxy"];
BrowserView browserView = new BrowserView()
{
Dock = DockStyle.Fill
};
engine = EngineFactory.Create(new EngineOptions.Builder
{
UserDataDirectory = contextDirectory,
SandboxDisabled = true,
RenderingMode = RenderingMode.OffScreen,
}.Build());
browserView.InitializeFrom(browser);
browser = engine.CreateBrowser();
browser.Navigation.FrameLoadFinished += delegate (object sender, FrameLoadFinishedEventArgs e)
{
Console.Out.WriteLine($"FrameLoadFinished: URL = {e.ValidatedUrl},"
+ $" IsMainFrame = {e.Frame.IsMain}");
};
}
I've got a method that returning back from CompletionService.GetDescriptionAsync(Document, CompletionItem) gives me the following description:
void SQL.GetSQLiteDB(string url) (+ 1 overload)
This is a method I made on a Xamarin project, here are both method signatures:
public static void GetSQLiteDB(string url);
public static string GetSQLiteDB(string url, string name);
What's the Roslyn way to get information on both?
Here's how I'm setting up completions:
async Task InitCodeCompletion()
{
host = MefHostServices.Create(MefHostServices.DefaultAssemblies);
workspace = new AdhocWorkspace(host);
Type[] types =
{
typeof(object),
typeof(System.Linq.Enumerable),
typeof(System.Collections.IEnumerable),
typeof(Console),
typeof(System.Reflection.Assembly),
typeof(List<>),
typeof(Type),
typeof(SQL)
};
imports = types.Select(x => x.Namespace).Distinct().ToImmutableArray();
assemblies = types.Select(x => x.Assembly).Distinct().ToImmutableArray();
references = assemblies.Select(t => MetadataReference.CreateFromFile(t.Location) as MetadataReference).ToImmutableArray();
compilationOptions = new CSharpCompilationOptions(
OutputKind.DynamicallyLinkedLibrary,
usings: imports);
projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), "Script", "Script", LanguageNames.CSharp, isSubmission: true)
.WithMetadataReferences(references).WithCompilationOptions(compilationOptions);
project = workspace.AddProject(projectInfo);
documentInfo = DocumentInfo.Create(DocumentId.CreateNewId(project.Id), "Script", sourceCodeKind: SourceCodeKind.Script,
loader: TextLoader.From(TextAndVersion.Create(SourceText.From(""), VersionStamp.Create())));
document = workspace.AddDocument(documentInfo);
var services = workspace.Services;
completionService = CompletionService.GetService(document);
}
async Task<CodeCompletionResults> GetCompletions(string code)
{
string codeModified = "using SQL = XamTestNET5.Services.SQLiteGeneratorService; " + Environment.NewLine;
codeModified += "using HtmlSvc = XamTestNET5.Services.HtmlRetrievalService;" + Environment.NewLine;
// ^^^ The above two lines set up some simple namespace aliases in my project, if you know how to put this in a separate project document and use it in code completion please let me know in comments as otherwise doing so gives me an exception that you can't have multiple syntax trees
codeModified += code;
var source = SourceText.From(codeModified);
document = document.WithText(source);
// cursor position is at the end
var position = source.Length;
var completions = await completionService.GetCompletionsAsync(document, position);
return new CodeCompletionResults() { InputCode = code, ModifiedCode = codeModified, Completions = completions };
}
Here's how I'm getting them now and putting them in a browser control:
private async void CSharpShellEnvironment_EntryCodeCompletionEntry(object sender, CSharpShellEnvironment.EntryEventArgs e)
{
if (e.Value != "")
{
CodeCompletionResults results = await GetCompletions(e.Value);
CompletionList list = results.Completions;
if (list != null)
{
if (list.Items != null)
{
StringBuilder sb = new StringBuilder();
foreach (var item in list.Items)
{
string spanText = (item.Span.Start != item.Span.End) ? results.ModifiedCode.Substring(item.Span.Start, item.Span.Length) : "";
bool recommended = spanText == "" ? true : item.DisplayText.StartsWith(spanText);
if (recommended)
{
string fText = item.DisplayText.Substring(spanText.Length);
string props = "";
foreach(var p in item.Properties)
{
props += $"<span data-key=\"{p.Key}\" data-value=\"{p.Value}\"></span>";
}
string tags = "";
foreach(var t in item.Tags)
{
tags += $"<span data-tag=\"{t}\"></span>";
}
string descStr = "";
if (item.Tags != null)
{
if (item.Tags.Where(x => x.ToLower() == "method").FirstOrDefault() != null && item.Tags.Where(x => x.ToLower() == "public").FirstOrDefault() != null)
{
var desc = await completionService.GetDescriptionAsync(document, item);
descStr += $"<span data-desc=\"{desc.Text}\">";
foreach(var part in desc.TaggedParts)
{
descStr += $"<span data-desc-part-tag=\"{part.Tag}\" data-desc-part-text=\"{part.Text}\"></span>";
}
descStr += "</span>";
}
}
sb.AppendLine($"<div class=\"codecompleteentry\" data-display-text=\"{item.DisplayText}\" data-span-text=\"{spanText}\" data-final-text=\"{fText}\">{props}{tags}{descStr}{fText}</div>");
}
}
string scriptInputClick = "Array.prototype.forEach.call(document.getElementsByClassName('codecompleteentry'), function(el) { el.addEventListener('click', function(elem) { var text = { MessageType: 'CodeCompletion', Parameters: JSON.stringify({ DataDisplayText: el.getAttribute('data-display-text'), DataSpanText: el.getAttribute('data-span-text'), DataFinalText: el.getAttribute('data-final-text') }), Message: el.innerText }; window.chrome.webview.postMessage(text); } ); });";
sb.AppendLine($"<script type=\"text/javascript\">{scriptInputClick}</script>");
env.EnterCodeCompletionResponse(sb.ToString());
}
else
{
env.EnterCodeCompletionResponse(strNoSuggestions);
}
}
else
{
env.EnterCodeCompletionResponse(strNoSuggestions);
}
}
else
{
env.EnterCodeCompletionResponse(strNoSuggestions);
}
}
It seems on the surface that CompletionSurface has everything you need, but it doesn't, you need to reference the Document's SemanticModel in order to get all of the signature overloads of a method when the user types ( on a method during code completion.
It wasn't very obvious to me until I started looking through the RoslynPad source, which I recommend doing for a practical example: https://github.com/aelij/RoslynPad
List<IEnumerable<ReferencedSymbol>> allMethodRefs = new List<IEnumerable<ReferencedSymbol>>();
async Task<CodeCompletionResults> GetCompletions(string code)
{
string codeModified = "using SQL = XamTestNET5.Services.SQLiteGeneratorService; " + Environment.NewLine;
codeModified += "using HtmlSvc = XamTestNET5.Services.HtmlRetrievalService;" + Environment.NewLine;
// ^^^ I put my namespace aliases in the same SyntaxTree for now,
// I'd like a better solution though.
codeModified += code;
var source = SourceText.From(codeModified);
document = document.WithText(source);
// cursor position is at the end
var position = source.Length;
var completions = await completionService.GetCompletionsAsync(document, position);
syntaxRoot = await document.GetSyntaxRootAsync();
semanticModel = await document.GetSemanticModelAsync();
var methods = syntaxRoot.DescendantNodes().OfType<InvocationExpressionSyntax>();
allMethodRefs = new List<IEnumerable<ReferencedSymbol>>();
if (methods != null)
{
if (methods.Count() > 0)
{
foreach(var m in methods)
{
var info = semanticModel.GetSymbolInfo(m);
if (info.Symbol != null)
{
allMethodRefs.Add(await SymbolFinder.FindReferencesAsync(info.Symbol, solution));
}
else
{
foreach(var symbol in info.CandidateSymbols)
{
allMethodRefs.Add(await SymbolFinder.FindReferencesAsync(symbol, solution));
}
}
}
}
}
return new CodeCompletionResults() { InputCode = code, ModifiedCode = codeModified, Completions = completions };
}
i am parsing a path from a directory location:
assuming that InitialPath = #"C:\Users\username\Documents\Visual Studio 2015\Projects"
and i have a loop of:
var list = new List<string>();
foreach(var folder in Directory.GetDirectories(InitialPath) {
var folder = Path.GetFileName(folder);
var file = Path.GetFileName(Directory.GetFiles(folder, "*.sln").Single());
list.Add(InitialPath + "\\" + folder + "\\" + file); //would then result something like "C:\Users\username\Documents\Visual Studio 2015\Projects\Folder1\Project1inFolder1.sln"
}
if i try a path from the list and assign it to a richbox as its .text value, it returns a single line text.
but when i'm displaying it on a MessageBox, the string is being broken into two lines as below:
i need to force it not to be broken into several lines. i mean, i need it to be a single line string only no matter the length of the string because Process.Start() wont accept the string because it gets cut into lines. see below for reference:
PS: sorry for not being able to explain my question eligibly, english is not my natural language
just in case, here is my code snippet:
using MaterialSkin;
using MaterialSkin.Controls;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Principal;
namespace The_Projects {
public partial class MainForm : MaterialForm {
public MainForm() {
InitializeComponent();
var materialSkinManager = MaterialSkinManager.Instance;
materialSkinManager.AddFormToManage(this);
materialSkinManager.Theme = MaterialSkinManager.Themes.LIGHT;
materialSkinManager.ColorScheme = new ColorScheme(Primary.BlueGrey800, Primary.BlueGrey900, Primary.BlueGrey500, Accent.LightBlue200, TextShade.WHITE);
}
public class DirectoryInformation {
private string _FolderName;
private string _Solution;
private DateTime _Created;
private DateTime _Accessed;
private DateTime _Modified;
private string _SecIdentity;
private string _NTAccount;
private double _FileSize;
private int _FileCount;
public string FolderName {
get { return _FolderName; }
set { _FolderName = value; }
}
public string Solution {
get { return _Solution; }
set { _Solution = value; }
}
public DateTime Created {
get { return _Created; }
set { _Created = value; }
}
public DateTime Accessed {
get { return _Accessed; }
set { _Accessed = value; }
}
public DateTime Modified {
get { return _Modified; }
set { _Modified = value; }
}
public string SecIdentity {
get { return _SecIdentity; }
set { _SecIdentity = value; }
}
public string NTAccount {
get { return _NTAccount; }
set { _NTAccount = value; }
}
public double FileSize {
get { return _FileSize; }
set { _FileSize = value; }
}
public int FileCount {
get { return _FileCount; }
set { _FileCount = value; }
}
}
public string InitialPath = #"X:\_\Document\Visual Studio 2015\Projects\";
public string FolderPath = string.Empty;
public string Solution = string.Empty;
private void MainForm_Load(object sender, EventArgs e) {
var projectList = new List<DirectoryInformation>();
foreach(var dirs in Directory.GetDirectories(InitialPath)) {
var ac = File.GetAccessControl(dirs);
var di = new DirectoryInfo(dirs);
var dirInf = new DirectoryInformation() {
FolderName = Path.GetFileName(dirs),
Solution = Path.GetFileName(Directory.GetFiles(dirs, "*.sln").Single()),
Created = Directory.GetCreationTime(dirs),
Accessed = Directory.GetLastAccessTime(dirs),
Modified = Directory.GetLastWriteTime(dirs),
SecIdentity = ac.GetOwner(typeof(SecurityIdentifier)).ToString(),
NTAccount = ac.GetOwner(typeof(SecurityIdentifier)).Translate(typeof(NTAccount)).ToString(),
FileSize = (double) di.EnumerateFiles("*.*", SearchOption.AllDirectories).Sum(x => x.Length) / 1024000,
FileCount = Directory.GetFiles(dirs, "*.*", SearchOption.AllDirectories).Count()
};
projectList.Add(dirInf);
}
lstProjectList.DataSource = projectList;
lstProjectList.DisplayMember = "FolderName";
}
private void lstProjectList_SelectedIndexChanged(object sender, EventArgs e) {
var project = lstProjectList.SelectedValue as DirectoryInformation;
lblFolder.Text = project.FolderName;
lblCreated.Text = project.Created.ToString();
lblAccess.Text = project.Accessed.ToString();
lblModified.Text = project.Modified.ToString();
lblIdentifier.Text = project.SecIdentity;
lblOwner.Text = project.NTAccount;
lblSize.Text = project.FileSize.ToString("F2") + " MB";
lblCount.Text = project.FileCount.ToString();
FolderPath = InitialPath + project.FolderName;
Solution = FolderPath + "\\" + project.Solution;
}
private void btnOpenProject_Click(object sender, EventArgs e) {
Process.Start(#"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe", Solution);
//Clipboard.SetText(Solution);
}
private void btnOpenFolder_Click(object sender, EventArgs e) {
Process.Start("explorer.exe", FolderPath);
}
}
}
It's just the way your MessageBox is wrapping text. You've got two options here:
Create a custom Forms class
Create a form dialog just for showing messages
EDIT:
Change this:
Process.Start(#"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe", Solution);
to
Process.Start(#"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe", "\"" + Solution + "\"");
What's happening here is the second parameter to the Process.Start method is treated as argument(s) for the executable given by the first parameter. So what process.start does is the equivalent (but not quite the same) of opening the command prompt and typing out:
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe" X:\_\Document\Visual Studio 2015\.....
and the command prompt treats (space) as a parameter separator, so it treats X:\_\Document\Visual as one parameter, Studio as the next and so on. When you use "\"" around the string you're telling Process.Start that the whole thing (including spaces) is a single parameter.
Your sample had some bugs in it, for me this worked and I got all *.sln files
//this is just to show that you can get short file name if you need FileInfo
var list = new Dictionary<string, string>();
var files = Directory.GetFiles(InitialPath, "*.sln", SearchOption.AllDirectories);
foreach (var file in files)
{
FileInfo fileInfo = new FileInfo(file);
list.Add(fileInfo.Name, file);
}
Process.Start(list.FirstOrDefault().Value);
On my computer starts with no problems.
But if you want a devenv.exe start with a solution open you do it like so
Process.Start(#"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe", #"devenv/""" + fullFilePath + #"""");
you need the command in arguments devenv/ and you must you must enclose paths in double quotation marks ("fullFilePath").
I'm working on a project in which I am creating a IronPython compiler depend on IronPython ,
But I have some problem on debugging the Script and can use breakpoint ? could you please give me some help ? thanks. all my code is there: [https://github.com/heyxEvget/IronPython-Debugger]
public ScriptEngine GetEngine()
{
if (_engine != null)
return _engine;
_engine = Python.CreateEngine();
_engine.Runtime.IO.SetOutput(_stream, Encoding.UTF8);
_engine.Runtime.IO.SetErrorOutput(_stream, Encoding.UTF8);
string path = Environment.CurrentDirectory;
string ironPythonLibPath = string.Format(#"{0}\IronPythonLib.zip", path);
var paths = _engine.GetSearchPaths() as List<string> ?? new List<string>();
paths.Add(path);
paths.Add(ironPythonLibPath);
path = Environment.GetEnvironmentVariable("IRONPYTHONPATH");
if (!string.IsNullOrEmpty(path))
{
var pathStrings = path.Split(';');
paths.AddRange(pathStrings.Where(p => p.Length > 0));
}
_engine.SetSearchPaths(paths.ToArray());
return _engine;
}
private void GetPythonVarsInfo(ScriptScope scope)
{
_varList.Clear();
var items = scope.GetItems();
foreach (var item in items)
{
_varList.Add(new VarValue
{
VarName = item.Key,
Value = item.Value
});
}
valueListView.ItemsSource = _varList;
}
private void OnExecuteButtonClick(object sender, ItemClickEventArgs e)
{
string outPutString = string.Empty;
outPutString = "*************************************" +
"Excute Date: " + DateTime.Now.ToLocalTime().ToString(CultureInfo.InvariantCulture);
ExeceutePython(document, outPutString);
TabControl.SelectedIndex = 2;
}
private void ExeceutePython(EditorDocument document, string outPutString)
{
ScriptEngine engine = GetEngine();
string script = document.Text;
ScriptSource source = engine.CreateScriptSourceFromString(script);
ScriptScope scope = _engine.CreateScope();
try
{
source.Compile();
OutputTextBox.AppendText(outPutString + Environment.NewLine);
var result = source.Execute(scope);
if (result != null)
{
OutputTextBox.AppendText(engine.Operations.Format(result));
}
OutputTextBox.AppendText(Environment.NewLine);
GetPythonVarsInfo(scope);
}
catch (Exception ex)
{
var eo = engine.GetService<ExceptionOperations>();
var eoString = eo.FormatException(ex);
OutputTextBox.AppendText(eoString);
return;
}
}
Given this setup code to create the IronPython script engine
var engine = IronPython.Hosting.Python.CreateEngine(new Dictionary<string, object> { { "Debug", ScriptingRuntimeHelpers.True }});
Debug.Assert(engine.Runtime.Setup.DebugMode);
var source = engine.CreateScriptSourceFromFile("script.py");
dynamic result = source.Execute();
You can then use
System.Diagnostics.Debugger.Break()
inside your scripts to get the debugger to break.
You can use visual studio isolated shell for that
Visual Studio Isolated Shell