Is there a Method to read the Content of a Website? - c#

I wanted to write a Program that reads an online Calendar, compares it with Names in a Database and uses this Data in some way. But if I use the WebClient, it reads the Source Code of the Website, not the Content. This is my Code:
using System;
using System.Diagnostics;
using System.Net;
using MySql.Data.MySqlClient;
namespace CalendarCrawler
{
class Program
{
static void KillTask(string Task)
{
Process[] Process = new Process[] { };
Process = Process.GetProcessesByName(Task);
foreach (Process Instance in Process)
{
Instance.Kill();
}
}
static String ReadContent(String Website)
{
WebClient web = new WebClient();
System.IO.Stream stream = web.OpenRead(Website);
using (System.IO.StreamReader reader = new System.IO.StreamReader(stream))
{
String text = reader.ReadToEnd();
return text;
}
}
static void Main(string[] args)
{
Console.WriteLine("Getting Connection ...");
var datasource = "localhost";//your server
var database = "database"; //your database name
var username = "username"; //username of server to connect
var password = "password"; //password
//your connection string
string connStr = $"Server={datasource};Database={database};Uid={username};Pwd={password}";
//create instanace of database connection
using (var conn = new MySqlConnection(connStr))
{
try
{
Console.WriteLine("Openning Connection ...");
//open connection
conn.Open();
Console.WriteLine("Connection successful!");
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
}
String Websitetext = ReadContent("http://www.esel.at/termine");
var stm = $"INSERT INTO content(Content) VALUES (#1);";
var cmd = new MySqlCommand(stm, conn);
cmd.Parameters.AddWithValue("#1", Websitetext);
cmd.ExecuteNonQuery();
Console.WriteLine(Websitetext);
KillTask("CalendarCrawler");
}
}
}
}
The Killtask Method is only to Clear it from the Background Processes, so there are no Problems with building a new Version.
I hope someone can help me.

There are effectively 2 different users of the web. People and computers. People like shiney things like buttons and tables (UI), computers prefer things like XML or JSON (API).
Your calendar web site has a UI, this is what you are currently seeing (both in a browser and when you 'download the code'). It probably has an API too and that is what you should be using in your program.
I've just had a quick look at esel.at and it doesn't appear to have a (public) API (but maybe that is because Google can't translate the page properly).

Related

Parallel read of SQL Server FileStream not working

I am trying to read the same SQL Server file stream in parallel threads, but am having no success.
Mostly I get the following exception (although from time to time I get a other errors):
System.InvalidOperationException: "The process cannot access the file specified because it has been opened in another transaction."
I have searched the internet, and found just a few posts, but as I understand this is supposed to work. I'm using SQL Server 2008 R2.
I've simplified the code to the following: the main code opens a main transaction, and then runs 2 threads in parallel, each thread using a DependentTransaction and copies the SQL Server file stream to a temporary file on the disk.
If I change threadCount to 1, then the code works.
Any idea why this fails?
The code:
class Program
{
private static void Main(string[] args)
{
string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
Directory.CreateDirectory(path);
try
{
using (var transactionScope = new TransactionScope(TransactionScopeOption.Required))
{
TransactionInterop.GetTransmitterPropagationToken(Transaction.Current);
const int threadCount = 2;
var transaction = Transaction.Current;
// Create dependent transactions, one for each thread
var dependentTransactions = Enumerable
.Repeat(transaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete), threadCount)
.ToList();
// Copy the file from the DB to a temporary files, in parallel (each thread will use a different temporary file).
Parallel.For(0, threadCount, i =>
{
using (dependentTransactions[i])
{
CopyFile(path, dependentTransactions[i]);
dependentTransactions[i].Complete();
}
});
transactionScope.Complete();
}
}
finally
{
if (Directory.Exists(path))
Directory.Delete(path, true);
}
}
private static void CopyFile(string path, DependentTransaction dependentTransaction)
{
string tempFilePath = Path.Combine(path, Path.GetRandomFileName());
// Open a transaction scope for the dependent transaction
using (var transactionScope = new TransactionScope(dependentTransaction, TransactionScopeAsyncFlowOption.Enabled))
{
using (Stream stream = GetStream())
{
// Copy the SQL stream to a temporary file
using (var tempFileStream = File.OpenWrite(tempFilePath))
stream.CopyTo(tempFileStream);
}
transactionScope.Complete();
}
}
// Gets a SQL file stream from the DB
private static Stream GetStream()
{
var sqlConnection = new SqlConnection("Integrated Security=true;server=(local);initial catalog=DBName");
var sqlCommand = new SqlCommand {Connection = sqlConnection};
sqlConnection.Open();
sqlCommand.CommandText = "SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()";
Object obj = sqlCommand.ExecuteScalar();
byte[] txContext = (byte[])obj;
const string path = "\\\\MyMachineName\\MSSQLSERVER\\v1\\DBName\\dbo\\TableName\\TableName\\FF1444E6-6CD3-4AFF-82BE-9B5FCEB5FC96";
var sqlFileStream = new SqlFileStream(path, txContext, FileAccess.Read, FileOptions.SequentialScan, 0);
return sqlFileStream;
}
}
kk

download two files from SFTP site [duplicate]

This question already has answers here:
SFTP Libraries for .NET [closed]
(8 answers)
Closed 4 years ago.
I'am using .NET 4.5 and I need to connect to an SFTP site and download two files to my local pc. From my reading on the internet there are no in built libraries I can use in .NET.
Are there any reliable 3rd parties that I can use that also have simple examples?
I have the following
username: myusername
password: mypassword
hostname: fts-sftp.myhost.com
protocol: SFTP
Port: 6621
Update
I have the code below however I am getting the following error message on the "sftp.Connect()" line.
An unhandled exception of type 'System.Net.Sockets.SocketException' occurred in System.dll
Additional information: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
Have checked the creditenals that have been supplied to me to make sure I have no typo's.
using Renci.SshNet;
using Renci.SshNet.Common;
using Renci.SshNet.Sftp;
namespace SftpExample2
{
class Program
{
static void Main(string[] args)
{
string host = "fts-sftp.myaddress.com";
string password = "mypassword";
string username = "myusername";
string remoteDirectory = ".";
int port = 6671;
using (SftpClient sftp = new SftpClient(host, port, username, password))
{
sftp.Connect();
var files = sftp.ListDirectory(remoteDirectory);
foreach (var file in files)
Console.WriteLine(file.FullName);
sftp.Disconnect();
};
}
}
}
I generaly use Renci.SshNet
below is an example of download, it should be trivial to change it for download.
I ripped it out of an old project, it might need some tuning to get it to compile/run
static public void UploadFiles(string [] files)
{
string host = " fts-sftp.myhost.com";
string userName = "user";
string password = "pass";
var keyboardAuthMethod = new KeyboardInteractiveAuthenticationMethod(userName);
keyboardAuthMethod.AuthenticationPrompt += delegate(Object senderObject, AuthenticationPromptEventArgs eventArgs)
{
foreach (var prompt in eventArgs.Prompts)
{
if (prompt.Request.Equals("Password: ", StringComparison.InvariantCultureIgnoreCase))
{
prompt.Response = password;
}
}
};
var passwordAuthMethod = new PasswordAuthenticationMethod(userName, password);
var connectInfo = new ConnectionInfo(host, userName, passwordAuthMethod, keyboardAuthMethod);
using (SftpClient serverConnection = new SftpClient(connectInfo))
{
try
{
foreach (var file in files)
{
if (!file.Name.StartsWith("."))
{
string remoteFileName = file.Name;
if (file.LastWriteTime.Date == DateTime.Today)
Console.WriteLine(file.FullName);
File.OpenWrite(localFileName);
string sDir = #"localpath";
Stream file1 = File.OpenRead(remoteDirectory + file.Name);
sftp.DownloadFile(remoteDirectory, file1);
}
serverConnection.Disconnect();
}
catch (Exception e)
{
throw e;
}
}
}
using Tamir.SharpSsh;
public void DownloadSFTP_Files()
{
string _ftpURL = "URLHERE";
string _SftpUserName = "USERNAMEHERE";
string _SftpPassword = "PASSWORDHERE";
int _port = 22;
Sftp oSftp = new Sftp(_ftpURL, _SftpUserName, _SftpPassword);
oSftp.Connect(_port);
string path = "";
// Get List of Files in the SFTP Directory
System.Collections.ArrayList GetFiles_List = oSftp.GetFileList(path);
// Download the Files Form SFTP Server to you Local system
string ServerPath= "SERVERDiRECTORYPATHHERE";
string LocalPath= "LOCALDiRECTORYPATHHERE";
oSftp.Get(ServerPath, LocalPath);
oSftp.Close();
}

SSH terminal in a webapp using ASP.NET

Hello I creating a webapp that has a working SSH terminal similar to Putty. I'm using SSH Library as a means of handling the ssh stream. However there is a problem. I can log into a Cisco 2950 and type in commands but it comes out jumbled and in one line.
Also when I try "conf t" it gets into the configuration terminal but then you can't do anything and this pops up "Line has invalid autocommand "?".
Here is the code I have so far:
This is the SSH.cs that interacts with the library.
public class SSH
{
public string cmdInput { get; set; }
public string SSHConnect()
{
var PasswordConnection = new PasswordAuthenticationMethod("username", "password");
var KeyboardInteractive = new KeyboardInteractiveAuthenticationMethod("username");
// jmccarthy is the username
var connectionInfo = new ConnectionInfo("10.56.1.2", 22, "username", PasswordConnection, KeyboardInteractive);
var ssh = new SshClient(connectionInfo);
ssh.Connect();
var cmd = ssh.CreateCommand(cmdInput);
var asynch = cmd.BeginExecute(delegate(IAsyncResult ar)
{
//Console.WriteLine("Finished.");
}, null);
var reader = new StreamReader(cmd.OutputStream);
var myData = "";
while (!asynch.IsCompleted)
{
var result = reader.ReadToEnd();
if (string.IsNullOrEmpty(result))
continue;
myData = result;
}
cmd.EndExecute(asynch);
return myData;
}
}
This the code in the .aspx.cs that displays the code on the web page.
protected void CMD(object sender, EventArgs e)
{
SSH s = new SSH();
s.cmdInput = input.Text;
output.Text = s.SSHConnect();
}
Any help would be appreciated.
From looking through the test cases in the code for the SSH.NET library, you can use the RunCommand method instead of CreateCommand, which will synchronously process the command. I also added a using block for the SshClient ssh object since it implements iDisposable. Remember to call Disconnect as well so you don't get stuck with open connections.
Also the SshCommand.Result property (used in the command.Result call below), encapsulates the logic to pull the results from the OutputSteam, and uses this._session.ConnectionInfo.Encoding to read the OutputStream using the proper encoding. This should help with the jumbled lines you were receiving.
Here is an example:
public string SSHConnect() {
var PasswordConnection = new PasswordAuthenticationMethod("username", "password");
var KeyboardInteractive = new KeyboardInteractiveAuthenticationMethod("username");
string myData = null;
var connectionInfo = new ConnectionInfo("10.56.1.2", 22, "username", PasswordConnection, KeyboardInteractive);
using (SshClient ssh = new SshClient(connectionInfo)){
ssh.Connect();
var command = ssh.RunCommand(cmdInput);
myData = command.Result;
ssh.Disconnect();
}
return myData;
}

SSH.NET RunCommand To Save Command Output to File

I'm trying to run a command on a remote server via SSH.
I need the output of the command that is run to be saved in a file on that remote server.
I've been attempting to this the following way
// ssh is the SshClient which is already set up
ssh.Connect();
ssh.RunCommand("echo 1 > C:\test.csv"); //Doesn't create a file
ssh.Disconnect();
Why doesn't this work with SSH.NET? If I run this via putty using the same credentials it works perfectly fine.
EDIT (Working Code):
I did some more playing around and have found the following to work:
// ssh is the SshClient which is already set up
ssh.Connect();
var shell = ssh.CreateShellStream("cmd.exe", 80, 24, 800, 600, 1024);
var reader = new StreamReader(shell);
var writer = new StreamWriter(shell);
writer.AutoFlush = true;
while (!shell.DataAvailable)
System.Threading.Thread.Sleep(1000); //This wait period seems required
writer.WriteLine("echo 1 > C:\test.csv");
while (!shell.DataAvailable)
System.Threading.Thread.Sleep(1000); //This wait period seems required
ssh.Disconnect();
While that works I still don't understand what's really happening here. Could someone explain?
Try this function:
Just save the result to a variable or write the result using StreamWriter
private void writeMe()
{
using (StreamWriter sw = new StreamWriter(filename)
{
string result = eSshCom(command);
sw.WriteLine(result);
}
}
private string eSshCom(string getCommand)
{
this.res = "";
var connectionInfo = new KeyboardInteractiveConnectionInfo(ipaddress, 22, username);
connectionInfo.AuthenticationPrompt += delegate(object asender, AuthenticationPromptEventArgs xe)
{
foreach (var prompt in xe.Prompts)
{
if (prompt.Request.Equals("Password: ", StringComparison.InvariantCultureIgnoreCase))
{
prompt.Response = password;
}
}
};
using (var ssh = new SshClient(connectionInfo))
{
ssh.Connect();
var cmd = ssh.RunCommand(getCommand);
this.res = cmd.Result;
ssh.Disconnect();
}
return this.res;
}

C# ApplicationContext usage

Apologies if my terminology is off, I'm new to C#. I'm trying to use an ApplicationContext file to store mysql conn values, like dbname, username, password. The class with mysql conn string is "using" the namespace for the ApplicationContext, but when I print out the connection string, the values are making it.
A friend said, "I'm not initializing it" but couldn't stay to expand on what "it" was.
and the "Console.WriteLine("1");" in ApplicationContext.cs never shows up. Do I need to create an ApplicationContext object and the call Initialize() on that object?
Thanks for any help.
ApplicationContext.cs:
namespace NewApplication.Context
{
class ApplicationContext
{
public static string serverName;
public static string username;
public static string password;
public static void Initialize()
{
//need to read through config here
try
{
Console.WriteLine("1");
XmlDocument xDoc = new XmlDocument();
xDoc.Load(".\\Settings.xml");
XmlNodeList serverNodeList = xDoc.GetElementsByTagName("DatabaseServer");
XmlNodeList usernameNodeList = xDoc.GetElementsByTagName("UserName");
XmlNodeList passwordNodeList = xDoc.GetElementsByTagName("Password");
}
catch (Exception ex)
{
// MessageBox.Show(ex.ToString());
//TODO: Future write to log file
username = "user";
password = "password";
serverName = "localhost";
}
}
}
}
MySQLManager.cs:
note: dbname is the same as the username as you'll see in the code, I copied this from a friend who does that.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data;
using MySql.Data.MySqlClient;
using NewApplication.Context;
namespace NewApplication.DAO
{
class MySQLManager
{
private static MySqlConnection conn;
public static MySqlConnection getConnection()
{
if (conn == null || conn.State == System.Data.ConnectionState.Closed)
{
string connStr = "server=" + ApplicationContext.serverName +
";user=" + ApplicationContext.username + ";database=" + ApplicationContext.username + ";port=3306;password=" +
ApplicationContext.password + ";";
conn = new MySqlConnection(connStr);
try
{
Console.WriteLine("Connecting to MySQL... ");
Console.WriteLine("Connection string: " + connStr + "\n");
conn.Open();
// Perform databse operations
// conn.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
return conn;
}
}
}
and, thanks for still reading, this is the code that uses the two previous files:
class LogDAO
{
MySqlConnection conn;
public LogDAO()
{
conn = MySQLManager.getConnection();
}
Thank you,
rd42
Ignoring that there's already a very rich set of Configuration Classes in .NET including ones for Connections that support encryption, you do need to as some point call Application.Initialize() in order for it fields to be populated.
I should mention that this looks like an implementation of a singleton. You might want to read Jon Skeet's article on singletons because there are probably things you want to watch out for. For example what would happen if two threads called ApplicationContext.Initialize()? Are multiple calls to ApplicationContext.Initialize() even sensible?
Also public fields are probably a bad idea especially when you have automatic implemented properties available to you.

Categories