How to retrieve a value/url? - c#

I apologize in advance as I have not used visual studio much before and I used a template for the most part to create the code below. But I really need some help.
I'm trying to generate a report from a system using visual studio through an API. The code below works and doesn't give me any errors when debugging, but I need to find a way to retrieve the reportURL variable at the end (the report is generated with the specifications below and I should receive a URL to download the report). I am building as a windows application.
Is there anything like console.log or console.writeline in visual studio I can use? Or can I output it to a textbox of some kind? (Again, I am building as a windows form and not a console application). Can anyone help me figure out some kind of code I can use to retrieve the URL based on what is provided below? (Please be detailed if possible as I am still getting used to the program). Thanks!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ReportsApplication2
{
using ServiceReference1;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ReportExecutionServiceClient client = new ReportExecutionServiceClient();
ReportSubmission submissionRequest = new ReportSubmission();
ReportSubmissionResponse submissionResponse = new ReportSubmissionResponse();
PollReportResponse pollResponse = new PollReportResponse();
WebMediaReportRequest webRepReq = new WebMediaReportRequest();
UserCredentials userCredentials = new UserCredentials();
DateFilter dateFilter = new DateFilter();
userCredentials.UserName = "xxxxx";
userCredentials.Password = "xxxxx";
submissionRequest.UserCredentials = userCredentials;
submissionRequest.DeveloperToken = "xxxxxx";
dateFilter.DateFilterType = DateFilterType.Total;
dateFilter.RelativeDateRange = RelativeDateRange.LastMonth;
webRepReq.Columns = new WebMediaReportColumn[2] { WebMediaReportColumn.MediaPlanName, WebMediaReportColumn.Impressions };
List<WebMediaFilter> webRepFilterList = new List<WebMediaFilter>();
WebMediaFilter webRepFilter = new WebMediaFilter();
webRepFilter.Column = WebMediaReportFilter.ClientGUID;
webRepFilter.Values = new string[1] {"xxxxxx"};
webRepFilterList.Add(webRepFilter);
webRepFilter = new WebMediaFilter();
webRepFilter.Column = WebMediaReportFilter.BuyGUID;
webRepFilter.Values = new string[1] { "xxxxxxxx" };
webRepFilterList.Add(webRepFilter);
webRepReq.ReportName = "test";
webRepReq.Filters = webRepFilterList.ToArray();
webRepReq.Format = FormatType.CSV;
webRepReq.DateFilter = dateFilter;
submissionRequest.ReportRequest = webRepReq;
submissionResponse = client.SubmitReport(submissionRequest);
string reportURL = string.Empty;
do { // Loop until report complete or failed
PollReportRequest pollRequest = new PollReportRequest();
pollRequest.DeveloperToken = "xxxxxxx";
pollRequest.UserCredentials = userCredentials;
pollRequest.ReportId = submissionResponse.ReportId;
pollResponse = client.PollReport(pollRequest);
reportURL = pollResponse.Url;
} while ((pollResponse.Status != ReportStatus.Failed) || ((pollResponse.Status != ReportStatus.Complete)));
}//end

You actually already know what you need. The Console.WriteLine method will write anything you want to the Console.
While you are debugging in Visual Studio, you can view the Console window by turning on the "Output" window. You can find it in the View menu
Even though you are writing a WinForms application, this will still write to the Output window while debugging. It can be an effective tool when debugging, but of course, when you actually publish the application, the command will be meaningless since you won't have a Console to write too.

If you are using Winforms, the simplest approach to show messages is MessageBox.Show():
MessageBox.Show(reportURL);
It will block the program until you click Ok.
http://msdn.microsoft.com/en-us/library/0x49kd7z(v=vs.110).aspx
If you want to output debug info during development, then Console.WriteLine() will work:
Console.WriteLine(reportURL);
It will show in the Output window. If you don't see that, go to the main menu in Visual Studio and select View -> Output, while in debug mode.
Console.WriteLine() will only work within Visual Studio for a Winforms app; after deploying it, the console window doesn't show, so you'll need to show it via a GUI method.
If you need to output it at runtime, either drag a TextBox from the toolbox onto your main form, and do:
textBox.Text = reportURL;
If you can't show it on the main form, then you may want to create your own custom message dialog that includes a TextBox and show it with ShowDialog()

The simplest solution is to use Console.WriteLine.

Related

Displaying a 2d data array from a console application

I am aware that there are already a few threads on this already created and closed (like 2-dimensional Integer array to DataGridView)
My problem is that since I have only been working with console applications, I am not aware of what I need to do in order to apply the code.
Up till now I have drag and dropped a new dataGridView and chose program.cs (where my main is) as a source. Now when I apply the code from the aforementioned link in program.cs, visualstudio is saying that dataGridView1 "does not exist in the current context". When I try to declare it beforehand, I get that the type/namespace can't be found. Any ideas?
With regard to the errors you got: All you need to do is add the namespace: using System.Windows.Forms; and also a reference to it! This works just fine for Console applications. Of course it will never show up but other than that you can make use of its abilities..
But the real question is: What do you want to achieve and why do you stick to a console application?
This is not to say that you may not have a good reason! For example it is sometimes necessary to run a service application without a display screen. This could still create output from DataGridViews or from Chart controls..
But it always helps to understand the situation fully when we answer questions here..
Here is an example that creates and fills a DataGridView DGV and then saves an image of the data to a png file.
For this to work you also need to add System.Drawing. As for Windows.Forms you need to add both the using clause and the reference:
(I have only a German VS version here; instead of the 'Aktuell' (ie 'Current') group you should search the references in the 'Framework'! The result is the same - I chose the other one becasue it is not so big on the screenshot..)
Once the references are in place..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; // <--- add namespace AND reference!!
using System.Drawing; // <--- add namespace AND reference!!
..this simple console application will compile and run:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataGridView DGV = new DataGridView();
List<string> test = new List<string>()
{ "Anna", "Bertha", "Carol", "Doreen", "Erica", "Fran", "Gisa" };
DGV.Columns.Add("No", "Number");
DGV.Columns.Add("Name", "Name");
DGV.Columns.Add("Age", "Age");
DGV.Columns["Name"].DefaultCellStyle.Font =
new Font(DGV.Font, FontStyle.Bold);
for (int i = 0; i < test.Count; i++) DGV.Rows.Add(new[]
{ (i + 1)+ "", test[i], i + 21 +""}); // cheap string array
DGV.ScrollBars = ScrollBars.None;
DGV.AllowUserToAddRows = false;
DGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
DGV.RowHeadersVisible = false;
var width = DGV.Columns.GetColumnsWidth(DataGridViewElementStates.None);
DGV.ClientSize = new Size(width,
DGV.ColumnHeadersHeight + DGV.RowCount * (DGV.Rows[0].Height) );
Bitmap bmp = new Bitmap(DGV.ClientSize.Width, DGV.ClientSize.Height);
DGV.DrawToBitmap(bmp, DGV.ClientRectangle);
bmp.Save("D:\\testDGV.png", System.Drawing.Imaging.ImageFormat.Png);
bmp.Dispose();
}
}
}

Very specific case regarding button click

I'm in a middle of process of creating utility console app to help me register to certain classes at my university. So far I've made it download website's content and frequently check for specific changes which gives me an information when the given course is full or available to be taken. Like that:
WebRequest request2 = WebRequest.Create("https://usosweb.umk.pl/kontroler.php?_action=katalog2/przedmioty/pokazPrzedmiot&prz_kod=0600-OG-ChH");
request2.Method = "GET";
WebResponse response2 = request2.GetResponse();
Stream stream2 = response2.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
string content_2 = reader2.ReadToEnd();
string drugi = getBetween(content_2, #"Stan zapełnienia grup:</b>
<b>", "</b> (zarejestrowanych/limit)");
reader2.Close();
response2.Close();
if (drugi != pierwszy)
{
Console.WriteLine("Rejestracja!");
Console.Beep(3200, 900);
System.Diagnostics.Process.Start("https://usosweb.umk.pl/kontroler.php?_action=katalog2/przedmioty/pokazPrzedmiot&prz_kod=0600-OG-ChH");
pierwszy = drugi;
}
The problem is that it still requires my full attention, as I made it only open the website with the registration buttton on and my goal is to make it actually click it automatically after the slot opens.
Few things to note:
I have to be logged on that website in order to be able to register at the course
http://i.imgur.com/DtBCG3Q.jpg <- this is how that button is coded. The chain_ function is named differently with every single refresh
http://i.imgur.com/tGX5kmy.jpg <- that is how the registration panel looks like. Ideally I want a website to open in a default browser (or somewhere with cache so I am already logged in) and automatically press that button, as it doesn't require additional confirmation.
links to one of websites at my university are included in the code above so you may have an additional look on how the buton is coded and how that case could be solved.
After all, is that even possible? Am I able to code it through? I'm using C# but some additional snippets of codes in other languagues could be put it, if that will make it easier or possible.
I think that for this kind of task automation Selenium WebDriver is the best tool
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Chrome;
namespace WEBDRIVER
{
class Program
{
static void Main(string[] args)
{
IWebDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl("http://www.google.com/");
IWebElement query = driver.FindElement(By.Name("q"));
query.SendKeys("banana");
query.Submit();
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until((d) => { return d.Title.ToLower().StartsWith("banana"); });
System.Console.WriteLine("Page title is: " + driver.Title);
driver.Quit();
}
}
}

Does not contain definition after reference has been added

I am VERY new to C# so it is possible this is a really easy problem, but even after all my reading I cant find a way to add the definitions Visual Studio 2010 wants despite having added the using statements and the references on the MSDN docs page for each expression.
My Error:
System.windows.forms does not contain a definition for document
I added the reference "presentationframework" based on something I was reading on the Microsoft site. Thanks to some of the comments below I discovered I was apparently mixing two different ways to get text from the box. All I need to be able to do is paste content into the textbox, and get the contents of the box when i press a button. Can someone tell (or better yet show) me definitively how to do this without mixing strategies?
Form1.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Documents;
using System.Windows.Controls.RichTextBox;
using System.Windows.Forms;
using System.Windows.Controls;
using System.Collections;
namespace WindowsFormsApplication1
{
public partial class HackController : Form
{
ArrayList ipList = new ArrayList();
ArrayList acctList = new ArrayList();
int myAcct = 0;
string myIp = "";
public HackController()
{
InitializeComponent();
}
public void sync_Click(object sender, EventArgs e)
{
string data = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd).Text;// ERROR HERE
string[] lines = Regex.Split(data, "\n");
Regex ipMatch = new Regex(#"\d+.\d+.\d+.\d+");
Regex acctMatch = new Regex(#"#\d+");
foreach(string line in lines)
{
foreach(Match m in ipMatch.Matches(line))
{
ipList.Add(m);
}
foreach( Match m in acctMatch.Matches(line))
{
acctList.Add(m);
}
}
}
}
}
Here's a (rather strange) sample showing one way to display data in a WinForms RichTextBox control. (Sorry, but it's the only sample I can find in my programming because I'm usually using Developer Express WinForms controls instead of the basic .Net ones.)
But first, to be 100% sure you are not mixing WinForms and WPF, make sure that when you create the project you select WinForms as the project template type (not WPF). And when you drag-and-drop the RichTextBox control from the Visual Studio toolbox onto your form, make sure it is the WinForms RichTextBox, not the WPF one.
You can check this by looking in the .Designer.cs file, and find the definition of the RTB control created by the Visual Studio designer. It should look something like this:
this.rtbResults = new System.Windows.Forms.RichTextBox();
...
...
//
// rtbResults
//
this.rtbResults.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.rtbResults.Location = new System.Drawing.Point(12, 52);
this.rtbResults.Name = "rtbResults";
this.rtbResults.Size = new System.Drawing.Size(640, 133);
this.rtbResults.TabIndex = 17;
this.rtbResults.Text = "";
...
...
private System.Windows.Forms.RichTextBox rtbResults;
The important thing being that it says "System.Windows.Forms.RichTextBox", not something else.
OK, here's my strange example, which displays the results of a Scrabble cheater program:
/// <summary>
/// Method to display the results in the RichTextBox, prefixed with "Results: " and with the
/// letters J, Q, X and Z underlined.
/// </summary>
private void DisplayResults(string resultString)
{
resultString = UnderlineSubString(resultString, "J");
resultString = UnderlineSubString(resultString, "Q");
resultString = UnderlineSubString(resultString, "X");
resultString = UnderlineSubString(resultString, "Z");
rtbResults.Rtf = #"{\rtf1\ansi " + "Results: " + resultString + "}";
}
/// <summary>
/// Method to apply RTF-style formatting to make all occurrences of a substring in a string
/// underlined.
/// </summary>
private static string UnderlineSubString(string theString, string subString)
{
return theString.Replace(subString, #"\ul " + subString + #"\ul0 ");
}
This uses Microsoft's proprietary Rich Text Format, but RichTextBox can also use straight text. And this demo only writes to the RTB, it doesn't read from it, although doing that is fairly trivial.
Hope this helps.

does not contain a definition for 'Form' ? Outlook Add-in

Recently I' am working on an add-in with c# for Outlook 2010 in Visual Studio 2012 . I developed a custom Form region which contains simple textboxes and a button. In Button_click method I' am taking an error (error Code : error CS0117) and I couldn't figure out why ? I am really new of this environment :) any way here it is my problem. (if you need more code to solve just let me know)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Office = Microsoft.Office.Core;
using Outlook = Microsoft.Office.Interop.Outlook;
using MSForms = Microsoft.Vbe.Interop.Forms;
.
.
.
private void button1_Click(object sender, EventArgs e)
{
// save button
MSForms.UserForm userForm = (MSForms.UserForm) FormRegion1.Form;
MSForms.Controls formControls = userForm.Controls;
Outlook.OlkTextBox ad =
(Outlook.OlkTextBox)formControls.Item("ad");
string cariad = ad.Text;
Outlook.OlkTextBox adres =
(Outlook.OlkTextBox)formControls.Item("adres");
string cariadres = adres.Text;
Outlook.OlkTextBox vergid =
(Outlook.OlkTextBox)formControls.Item("vergid");
string carivergid = vergid.Text;
.
.
.
*MSForms.UserForm userForm = (MSForms.UserForm) in line FormRegion1.Form "Form" is not recognized. And error says
" error CS0117: 'OutlookAddIn2.FormRegion1' does not contain a
definition for 'Form'".
Thanks a lot.
I solved that problem with not using Forms:) Simply, I just typed
this.TextBoxName.Text;
to reach the text of the textBox. Thanks any way.

winform Close self plus another WebBrowserControl

i know i could search proccessId / name of running tasks and kill processes i need .
though till now i was not developing schedualed tasks / self executble Applications,
so i didn't need to know how to make the application close itself after execition
trying to close everything (including WebDriver) via Application.Exit + OR this.Close()
right after i have got what i was looking for. mission Complete .
please close ... no more work for you .
but mr . Program.cs still needs somthing from Form1.
saying somthing about
Cannot access a disposed object.
Object name: 'Form1'.
any combination of both was returning in some point an exeption error
(from program.cs ) even though mission complete . no more code was requested .(?) by me..atleast.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;
using System.IO;
namespace HT_R_WbBrows2
{
public partial class Form1 : Form
{
public IeEnginGenerator Iengn = new IeEnginGenerator();
public Form1()
{
InitializeComponent();
//setLogView(View.Details);
string extractededVal = Iengn.ExtractPageValue(Iengn.itrfWebEng);
string flnm = #" the directory path to file --> \dolarRate.asp";
File.WriteAllText(fn, extractededVal);
this.Close();
Application.Exit();
}
public class IeEnginGenerator
{
private string directory = Environment.CurrentDirectory;///Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
public IWebDriver IwebEngine;
public List<string> ListElementsInnerHtml = new List<string>();
public HtmlAgilityPack.HtmlDocument Dnetdoc = new HtmlAgilityPack.HtmlDocument();
#region <<=========== setupDriver ============>>
public string ExtractPageValue(IWebDriver DDriver, string url="")
{
if(string.IsNullOrEmpty(url))
url = #"http://www.boi.org.il/he/Markets/ExchangeRates/Pages/Default.aspx";
var service = InternetExplorerDriverService.CreateDefaultService(directory);
service.LogFile = directory + #"\seleniumlog.txt";
service.LoggingLevel = InternetExplorerDriverLogLevel.Trace;
var options = new InternetExplorerOptions();
options.IntroduceInstabilityByIgnoringProtectedModeSettings = true;
DDriver = new InternetExplorerDriver(service, options, TimeSpan.FromSeconds(60));
DDriver.Navigate().GoToUrl(url);
Dnetdoc.LoadHtml(DDriver.PageSource);
string Target = Dnetdoc.DocumentNode.SelectNodes("//table//tr")[1].ChildNodes[7].InnerText;
//.Select(tr => tr.Elements("td").Select(td => td.InnerText).ToList())
//.ToList();
return Math.Round(Convert.ToDouble(Target), 2).ToString();
//return "";//Math.Round(Convert.ToDouble( TempTxt.Split(' ')[10]),2).ToString();
}
#endregion
}
}
}
Why use a winform application? A Console application would probably suffice for what you are doing. Once Main() ends your app will close as well. Main() never ends in a winform app because of the applications runloop.
Edit:
Here would be the correct way to do this. You need to register to the forms Load event and run your code there, not in the constructor. You can't close a winform from inside a constructor.
Edit 2: Put this code in the Form1() constructor. Somewhere after InitializeComponent();
this.Load += (sender,args)=>{ /*do all your work here*/
string extractededVal = Iengn.ExtractPageValue(Iengn.itrfWebEng);
string flnm = #" the directory path to file --> \dolarRate.asp";
File.WriteAllText(fn, extractededVal);
Application.Exit();
};

Categories