I am Using the below code to fetch a file from database and print it with the selected printer from Installed Printers populated in the Dropdownlist, my problem is during using the Printjob.Start() it throws the Exception The System cannot find the file specified
My code is,
protected void ggvqpdetail_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName.ToUpper().ToString() == "PRINTREC")
{
try
{
// Set the printer to a printer in the dropdown box when the selection changes.
PrintDocument printDoc = new PrintDocument();
string a = TextBox1.Text + TextBox2.Text + TextBox3.Text;
DataSet ds = ExamManagement.SP.Eval_QP_PrintSelect(a).GetDataSet();
if (ddlprint.SelectedIndex != -1 && ds.Tables[0].Rows.Count > 0)
{
// The dropdown box's Text property returns the selected item's text, which is the printer name.
printDoc.PrinterSettings.PrinterName = ddlprint.Text;
Process printJob = new Process();
printJob.StartInfo.FileName = ds.Tables[0].Rows[0]["Data"].ToString();
printJob.StartInfo.UseShellExecute = true;
printJob.StartInfo.Verb = "printto";
printJob.StartInfo.CreateNoWindow = true;
printJob.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
printJob.StartInfo.Arguments = ddlprint.Text;
printJob.StartInfo.WorkingDirectory = Path.GetDirectoryName(ds.Tables[0].Rows[0]["Data"].ToString());
printJob.Start();
}
}
catch(Exception ex)
{
Lblmsg.Visible = true;
Lblmsg.Text = ex.Message;
}
}
}
Obviously the problem would depends on that you actually place in that printJob.StartInfo.FileName. The value comes from the database, so the only person capable of investigating it is you. Look what filename you have in ds.Tables[0].Rows[0]["Data"] and make sure is a file that exists and you have access to in on your local client where you're trying to print from. That, of course, also reveals the weakness of your solution which seems to store filenames in the database and expect the name to be a valid local file on each client. Very unlikely to be true.
Related
I am new to learning C#, and i'm attempting to create a WPF application that asks the user questions. I then convert those answers into strings and export them to a CSV file.
One of the questions is "Pick a number between 1-5". I need to make this so that if a number is less than 1, or more than 5, it asks the user to pick a different number. I tried to achieve this by using the below code. It somewhat works because when i click save as, nothing will happen if i use a wrong number. But it doesn't ask the user like i want it to. Please could someone take a look at my code and let me know why this isn't working?
private void btnSaveClick(object sender, RoutedEventArgs e)
{
try
{
string firstName = tbFirstName.Text;
string lastName = tbLastName.Text;
string jobTitle = tbJobTitle.Text;
string chickenEgg = tbChickenEgg.Text;
string _oneFive = tbNumber.Text;
int oneFive = Convert.ToInt32(_oneFive);
if ((oneFive > 5) || (oneFive < 1))
{
throw new System.ArgumentException("Please use a number between 1-5");
}
string csvContent = string.Format("{0},{1},{2},{3},{4}", FormatCSV(firstName), FormatCSV(lastName), FormatCSV(jobTitle), FormatCSV(chickenEgg), FormatCSV(_oneFive));
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "CSV file (*.csv)|*.csv";
if (saveFileDialog.ShowDialog() == true)
File.WriteAllText(saveFileDialog.FileName, csvContent);
tbFirstName.Clear();
tbLastName.Clear();
tbJobTitle.Clear();
tbChickenEgg.Clear();
tbNumber.Clear();
tbFirstName.Focus();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}
}
static string FormatCSV(string _input)
{
try
{
string result = "";
if ((_input.Contains(",")) || (_input.Contains(" ")))
{
result = string.Format("\"{0}\"", _input.Trim());
}
else
{
result = _input.Trim();
}
return result;
}
catch (Exception e)
{
throw e;
}
When i get to the catch block, nothing displays or seems to happen.
Thank you in advance!
Instead of throwing an exception, you could display a MessageBox to the user:
private void btnSaveClick(object sender, RoutedEventArgs e)
{
string firstName = tbFirstName.Text;
string lastName = tbLastName.Text;
string jobTitle = tbJobTitle.Text;
string chickenEgg = tbChickenEgg.Text;
string _oneFive = tbNumber.Text;
int oneFive = Convert.ToInt32(_oneFive);
if ((oneFive > 5) || (oneFive < 1))
{
MessageBox.Show("Please use a number between 1-5", "", MessageBoxButton.OK, MessageBoxImage.Information);
}
else
{
string csvContent = string.Format("{0},{1},{2},{3},{4}", FormatCSV(firstName), FormatCSV(lastName), FormatCSV(jobTitle), FormatCSV(chickenEgg), FormatCSV(_oneFive));
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "CSV file (*.csv)|*.csv";
if (saveFileDialog.ShowDialog() == true)
File.WriteAllText(saveFileDialog.FileName, csvContent);
tbFirstName.Clear();
tbLastName.Clear();
tbJobTitle.Clear();
tbChickenEgg.Clear();
tbNumber.Clear();
tbFirstName.Focus();
}
}
The user can then click "OK" to dismiss the message box and then enter a new number and hit the "Save" button again. This is basically how GUI applications tend to work.
If you want to tell the user something, the simple way to do it is with a message box
MessageBox.Show("enter a number between 1 and 5");
A better, but a little bit more complicated is to use binding validation. This will reject input as soon as it is entered.
It might be a good idea to read Best practices for exceptions, one rule is to handle common conditions without throwing exceptions, and an incorrect input value would be one of these common cases.
I catch an exception in my code for a wrong file type. Then i would like to change my file and use the correct file. How do i close the execption to look fresh at the new file and process it.
below is my code. one is a main function. the second is a called function.
main function.
//data file process button
private void button9_Click(object sender, EventArgs e)
{
try
{
panel1.Visible = false; // File paths (Admin Access))
panel3.Visible = true; // File process status
label6.Visible = true; // label - File process status
panel4.Visible = false; // Admin authenticate
InitializeFile();
ParseListFileData();
ListArrayFileData();
CleanDesiredData();
GetRRData();
GetLecoData();
//cleanup();
textBox5.Text += "All RR & Leconum data processing from file - " + textfilename + " completed." + "\r\n";
textBox5.Text += "Please click EXIT to close HORIBA program" + "\r\n";
}
catch(IndexOutOfRangeException)
{
//cleanup();
textBox5.Text += "Bad File" + "\r\n";
datafilepath = "";
textBox5.Text += "Select correct file" + "\r\n";
}
}
The Called Function ParseListFileData();
public void ParseListFileData()
{
//Opens file and uses for processing
System.IO.StreamReader sr = new
System.IO.StreamReader(datafilepath);
try
{
//while loop to read file till end of file
while (!sr.EndOfStream)
{
//split data in file into differend fields
var Row = sr.ReadLine();
var values = Row.Split(',');
ColmnA.Add(values[0]);
ColmnB.Add(values[1]);
ColmnC.Add(values[2]);
ColmnD.Add(values[3]);
ColmnE.Add(values[4]);
ColmnF.Add(values[5]);
ColmnG.Add(values[6]);
ColmnH.Add(values[7]);
ColmnI.Add(values[8]);
ColmnJ.Add(values[9]);
ColmnK.Add(values[10]);
ColmnL.Add(values[11]);
ColmnM.Add(values[12]);
ColmnN.Add(values[13]);
}
sr.Close();
sr.Dispose();
}
catch (IndexOutOfRangeException e)
{
sr.Close();
sr.Dispose();
datafilepath = "";
//cleanup();
//print(e.Message.("Error encountered");
textBox5.Text += "File type not correct or missing data in file "+ e + "\r\n";
}
}
As soon as i select a new good working file, the old exception seems closed, but the old file still remains in use and shows an exception at another function. Even though i i use dispose() to close the streamreader resources.
How can i start fresh with a new file.
Im not sure what exactly is the problem, is the file handle not closed.
I see a problem with your code: you try and catch, but only on a specific exception, say you get an ArgumentException, this will not be caught, instead you can use try{}catch{}finaly{}
try
{
/blabla
}
catch (IndexOutOfRangeException e)
{
datafilepath = "";
//cleanup();
//print(e.Message.("Error encountered");
textBox5.Text += "File type not correct or missing data in file "+ e + "\r\n";
}
finaly
{ //this codes always runs wether exception or not.
sr.Close();
sr.Dispose();
}
alternative and easier solution is to use using (which closes disposables automatically when done):
using(var sr = new System.IO.StreamReader(datafilepath);) {
//try catch in here. even is something goes horribly wrong. StreamReader = fileHandle will be closed.
}
I am writing an application that is supposed to open a certain process on the click of a button. However, the user has the ability to add new buttons. I'm using the following code for the action that occurs that starts the process on button click:
private void StartProcess(string path)
{
ProcessStartInfo StartInformation = new ProcessStartInfo();
StartInformation.FileName = path;
Process process = Process.Start(StartInformation);
process.EnableRaisingEvents = true;
}
private void ClickFunc(object sender, RoutedEventArgs e)
{
if (File.Exists(ProgramPath))
{
StartProcess(ProgramPath);
}
else
{
MessageBox.Show("Specified path does not exist, please try again.", "Bad File Path Error", MessageBoxButton.OK);
}
}
What I'm trying to accomplish is, when the user creates a button for a webpage, it opens the browser, then the webpage. Any ideas?
Thank you in advance!
To start a process to open the browser with a specific url you can try this:
string url = "http://www.stackoverflow.com";
var process = System.Diagnostics.Process.Start(url);
But sometimes if you have problems with the path of your browser, it cannot work properly. The function bellow gives you the path of the browser in the machine.
public static string GetDefaultBrowserPath()
{
string urlAssociation = #"Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http";
string browserPathKey = #"$BROWSER$\shell\open\command";
RegistryKey userChoiceKey = null;
string browserPath = “”;
try
{
//Read default browser path from userChoiceLKey
userChoiceKey = Registry.CurrentUser.OpenSubKey(urlAssociation + #"\UserChoice", false);
//If user choice was not found, try machine default
if (userChoiceKey == null)
{
//Read default browser path from Win XP registry key
var browserKey = Registry.ClassesRoot.OpenSubKey(#"HTTP\shell\open\command", false);
//If browser path wasn’t found, try Win Vista (and newer) registry key
if (browserKey == null)
{
browserKey =
Registry.CurrentUser.OpenSubKey(
urlAssociation, false);
}
var path = CleanifyBrowserPath(browserKey.GetValue(null) as string);
browserKey.Close();
return path;
}
else
{
// user defined browser choice was found
string progId = (userChoiceKey.GetValue("ProgId").ToString());
userChoiceKey.Close();
// now look up the path of the executable
string concreteBrowserKey = browserPathKey.Replace(“$BROWSER$”, progId);
var kp = Registry.ClassesRoot.OpenSubKey(concreteBrowserKey, false);
browserPath = CleanifyBrowserPath(kp.GetValue(null) as string);
kp.Close();
return browserPath;
}
}
catch(Exception ex)
{
return "";
}
}
And you can use the path of the browser and the url of website, for sample:
string url = "http://www.stackoverflow.com";
var process = System.Diagnostics.Process.Start(GetDefaultBrowserPath(), url);
In the url string you can pass the webpage link. It will open the browser with the url.
See more:
http://www.seirer.net/blog/2014/6/10/solved-how-to-open-a-url-in-the-default-browser-in-csharp
I have a c# program which does the following on form load:
Creates an OleDbConnection to a database in the same folder as the program
Gets the computer name
Gets the username
Fills in some textbox fields on the form with data obtained from the database
When I open the form using Windows explorer, shortcut, or debugging in visual studio express 2013, it does all of this without any issues. When trying to open it with a command prompt or with a hyperlink, the database connection is not established, but no error messages appear. The textbox fields are filled with "not found" as a result of my try-catch statements around the oledb commands. The same try-catch statement should print ex.message to a text file, but that does not happen either. As stated before, this all runs flawlessly when running from debug mode in vs or running the program by opening it in Windows explorer, so I'm not sure how to debug this.
2 questions - Is there a known problem with opening c# forms which try to establish OleDb connections with access databases on form load when launching the program from command prompt or a shortcut? If so, are there any workarounds? Given that it runs fine in debug mode in vs, and my catch statements seem to be terminating prematurely without error messages, is there any other way to debug and find out exactly where the problem occurs?
I left off some of the irrelevant lines of code to make this shorter.
private void Form1_Load(object sender, EventArgs e)
{
userData = onLoad.loadDb(out userNotFound);
ComputerName = onLoad.getComputer();
// Session Notification
WTSRegisterSessionNotification(this.Handle, NotifyForThisSession);
// Initialize Hooks
initialize_Hooks();
if (userData.Count < 4)
{
for(int i = 0; i<4; i++) { userData.Add("Not Found"); }
}
// globals:
FullID = userData[0];
ID = userData[2];
firstName = userData[1];
lastName = userData[0];
nanid = userData[3];
fullName = firstName + " " + lastName;
// Fill in Form
label1.Text = fullName;
label2.Text = ID;
label3.Text = nanid;
}
public class onLoad
{
public static string getUser() // returns Environment.UserName
public static string getComputer() // returns System.Environment.MachineName;
public static List<string> loadDb(out bool userNotFound)
{
List<string> rList = new List<string>();
string strAccessConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=db.mdb";
string strAccessSelect = "SELECT (//select statement which works fine when I open the program in explorer or vs debug)
DataSet myDataSet = new DataSet();
OleDbConnection myAccessConn = null;
try
{
myAccessConn = new OleDbConnection(strAccessConn);
}
catch(Exception ex)
{
for(int i = 0; i<4; i++) { rList.Add("Not Found"); }
error_handler.error_logger(ex.Message);
userNotFound = true;
return rList;
}
try
{
OleDbCommand myAccessCommand = new OleDbCommand(strAccessSelect, myAccessConn);
OleDbDataAdapter myDataAdapter = new OleDbDataAdapter(myAccessCommand);
myAccessConn.Open();
myDataAdapter.Fill(myDataSet,"table1");
}
catch (Exception ex)
{
error_handler.error_logger(ex.Message);
userNotFound = true;
for(int i = 0; i<4; i++) { rList.Add("Not Found"); }
return rList;
}
finally
{
myAccessConn.Close();
}
try
{
DataRowCollection dra = myDataSet.Tables[0].Rows;
foreach (DataRow dr in dra)
{
code that conditions the data, works fine when running the program
}
}
catch(Exception ex)
{
string returnString = ex.Message;
error_handler.error_logger(ex.Message);
userNotFound = true;
for(int i = 0; i<4; i++) { rList.Add("Not Found"); }
return rList;
}
return rList;
}
}
class error_handler
{
public static string filename = "error.txt";
public static void error_logger(string error_message)
{
error_message = onLoad.getUser() + "\t" + DateTime.Now.ToString("MM/dd/yy hh:mm:ss") + "\t" + onLoad.getComputer() + "\t" + "Error: " + error_message;
if (!File.Exists(filename))
//writes error_message to a new text file or appends if it already exists. works fine when running from windows explorer or vs debug
}
}
I bet that shortcut passes in the working directory as a parameter. The documentation for File.Exists() states that when using a relative path the relative path information is interpreted as relative to the current working directory.
You can use the Directory.GetCurrentDirectory() function to determine if the path is set correctly.
If you are using files that you know are going to be in a path relative to the application I would use Application's path or at least set Environment.CurrentDirectory = Application's path.
Also take a look at the Environment.GetCommandLineArgs()[0]. That is probally being set by the shortcut.
I have a buttton on the click event of which I am calling a function.I have set the accept button property to that button.But it is not firing the event on single click.
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
//Function call for validating the textboxes entry
ValidateForm();
if(lblMessage.Text != string.Empty)
{
//Function call for binding the dropdown with all DB names
BindDBDropDown();
//Function call for binding the operation names in dropdown
SetOperationDropDown();
}
else
{
//Else give the error message to user
lblMessage.Text = "Invalid Credentials";
}
}
catch(Exception ex)
{
//All the exceptions are handled and written in the EventLog.
EventLog log = new EventLog("Application");
log.Source = "MFDBAnalyser";
log.WriteEntry(ex.Message);
}
}
public void BindDBDropDown()
{
SqlConnectionStringBuilder objConnectionString = new SqlConnectionStringBuilder();
objConnectionString.DataSource = txtHost.Text;
objConnectionString.UserID = txtUsername.Text;
objConnectionString.Password = txtPassword.Text;
SqlConnection sConnection = new SqlConnection(objConnectionString.ConnectionString);
//If connected then give this message to user
lblMessage.Visible = true;
lblMessage.Text = "You are connected to the SQL Server....";
try
{
//To Open the connection.
sConnection.Open();
//Query to select the list of databases.
string selectDatabaseNames = #"SELECT
NAME
FROM
[MASTER]..[SYSDATABASES]";
//Create the command object
SqlCommand sCommand = new SqlCommand(selectDatabaseNames, sConnection);
//Create the data set
DataSet sDataset = new DataSet("master..sysdatabases");
//Create the dataadapter object
SqlDataAdapter sDataAdapter = new SqlDataAdapter(selectDatabaseNames, sConnection);
sDataAdapter.TableMappings.Add("Table", "master..sysdatabases");
//Fill the dataset
sDataAdapter.Fill(sDataset);
//Bind the database names in combobox
DataViewManager dsv = sDataset.DefaultViewManager;
//Provides the master mapping between the sourcr table and system.data.datatable
cmbDatabases.DataSource = sDataset.Tables["master..sysdatabases"];
cmbDatabases.DisplayMember = "NAME";
cmbDatabases.ValueMember = ("NAME");
}
catch(Exception ex)
{
//All the exceptions are handled and written in the EventLog.
EventLog logException = new EventLog("Application");
logException.Source = "MFDBAnalyser";
logException.WriteEntry(ex.Message);
MessageBox.Show ("Login Failed!!", "Error Occured");
}
finally
{
//If connection is not closed then close the connection
if(sConnection.State != ConnectionState.Closed)
{
sConnection.Close();
}
}
}
Can anybody help me out??
Uh, on the first click, does lblMessage contain any text?
Because if not, the first time you run it, it will fail the conditional test and insert the string "Invalid Credentials" into the label. Then, the second time you run it, it will pass the conditional test and call the BindDBDropDown method as you're expecting.
Specifically, this section of your code:
if(lblMessage.Text != string.Empty)
{
//Function call for binding the dropdown with all DB names
BindDBDropDown();
//Function call for binding the operation names in dropdown
SetOperationDropDown();
}
else
{
//Else give the error message to user
lblMessage.Text = "Invalid Credentials";
}
I assume that you're either trying to check that the contents of a textbox where the user has entered their credentials are not empty, or that you want to make sure an error message is not currently displayed in lblMessage. Make sure that your code accurately reflects your intentions!