Get the path of the file that launched my app - c#

I'm working in my own PDF Reader using C# & Patagames/PDFium library and I am able to open files using "OpenFileDialog" and show them on the screen. However, due requirements of the boss I am not allowed to have any buttons in the screen. All we want is to click the any .PDF file (For example, in this route: C:\Users\Adaptabilidad\Desktop\Test.pdf) and launch it & show the PDF document directly, without looking for the directory of the file. I've set my ".exe" as default app, although, the PDF Reader is executed no PDF file is displayed.
I've tried Application.ExecutablePath, Application.StartUpPath after initializing the component and I'm still getting the route of my PDF reader executable (.Exe) but I need to know what the file to be open is (filepath).
How can I get the information about the .pdf file (directory can vary) that is launching my app? You can see my code below if helps.
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;
using Patagames;
using System.IO;
namespace aPDF
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "PDF Files (*.pdf)|*.pdf";
if (dialog.ShowDialog() == DialogResult.OK)
{
openfile(dialog.FileName);
}
}
public void openfile(string filepath)
{
byte[] bytes = System.IO.File.ReadAllBytes(filepath);
var stream = new MemoryStream(bytes);
Patagames.Pdf.Net.PdfDocument pdfDocument = Patagames.Pdf.Net.PdfDocument.Load(stream);
pdfViewer1.Document = pdfDocument;
}
}
}
Updates:
I've found a way. One of you guys that commented allowed me to find out how to do it.
What I used is the following sentence in my Program.cs:
public static string[] cmdLine = Environment.GetCommandLineArgs();
public static string cmd = cmdLine[1];
Then, y use "cmd" as filepath.
Why? Environment.GetCommandLineArgs(); returns 2 values, the .exe you're executing (your program) & as second value the file that you've used in order to launch that .exe.
That's it. Thank you for your answers.

Related

WinForms how to open file in resources folder

I am new in WinForms technology. I am using .NET Framework 4.8 , Microsoft Visual Studio 2019. I put file in Resources folder.
I tried something like this
using DevExpress.XtraBars;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace accwf
{
public partial class NhapSoDu : DevExpress.XtraBars.Ribbon.RibbonForm
{
public NhapSoDu()
{
InitializeComponent();
}
private void simpleButton1_Click(object sender, EventArgs e)
{
Console.WriteLine(System.AppDomain.CurrentDomain.BaseDirectory);
Process.Start(".../B01-DN_01_Summary.xlsx");
}
}
}
please guide me finish it.
I do this in one of my applications to open a XLSX file that is an embedded resource in my application
private void buttonOpenTemplate_Click(object sender, EventArgs e)
{
byte[] templateFile = Properties.Resources._01__So_du_tai_khoan; // This is your Excel document in the application Resources
string tempPath = $"{Path.GetTempFileName()}.xlsx";
using (MemoryStream ms = new MemoryStream(templateFile))
{
using(FileStream fs = new FileStream(tempPath, FileMode.OpenOrCreate))
{
ms.WriteTo(fs);
fs.Close();
}
ms.Close();
}
Process.Start(tempPath);
}
This requires a reference to System.IO for access to the MemoryStream and FileStream classes.
You are currently only outputting the base directory. Along with that, you're only looking for files within that base directory. Execution happens from the base directory, so your program is looking for ..\Path\to\exe\B01-DN_01_Summary.xlsx when it should be looking for ..\Path\to\exe\Resources\FilesHere\ImportExcel\B01-DN_01_Summary.xlsx
To note: embedding resources files into your application is not recommend. It's preferable to instead store their locations and allow the application to traverse your directories to find the specified file locations.
Here's an adapted version you can try:
You will need to make sure that the Copy to Output Directory property for you desire file is set to "Copy Always" or "Copy if Newer". This will ensure the directory path is created in your output directory.
namespace accwf
{
public partial class NhapSoDu : DevExpress.XtraBars.Ribbon.RibbonForm
{
public NhapSoDu()
{
InitializeComponent();
}
private void simpleButton1_Click(object sender, EventArgs e)
{
string resourcePath = System.IO.File.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Resources\\FilesHere\\ImportExcel\\B01-DN_01_Summary.xlsx")
if (File.Exists(resourcePath))
{
MessageBox.Show("Exists");
}
else
{
MessageBox.Show("Doesn't Exist");
}
Process.Start(resourcePath);
}
}
}
This is an example of how I get PDF file documentation for a help menu I have:
public void MyMethod()
{
// helpMenuPath is a global var set to something like: Area/MyApp/Resources/
string filePath = helpMenuPath;
string[] fileNames = new string[0]; // Initialize the variable with length of 0. Directory.GetFiles() will allow for this length to be overwritten
// Try/Catch in case bad dir
try
{
fileNames = Directory.GetFiles(filePath);
}
catch (IOException ioe)
{
// error catch for if bad dir
MessageBox.Show($"Error in getting files: {ioe.Message}");
}
// Do something with files ...
}

How to create file using streamwriter in c# in which the content is inputed by users using cmd

I created a console application which accepts arguments. After building the program i will run it through cmd in which the user will input like this "filemgr.exe create [filename] [contents]" . My code is below. I want to enter "my text here" content, but when i check the output, only the FIRST word is displayed which is the "my", how to include the rest of the strings?(which is the text here)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace filemgr
{
class Program
{
static void Main(string[] args)
{
if (args[0]=="create")
{
using (StreamWriter file = new StreamWriter(args[1]))
{
file.Write(args[2]);
}
}
}
}
}
You need to recombine the args array into a string (although this method will likely lose quotes):
file.Write(string.Join(" ", args.Skip(2)));
Alternatively you can quote the string in the commandline:
program.exe create test.txt "hello this is a message"
Also, if you want to append to the file through sequential calls you need to open the stream like so:
using (StreamWriter file = new StreamWriter(args[1], true))
This signifies that you want append mode, and not create/replace.
Pass content args in double quotes
filemgr.exe create [filename] "[contents]"
filemgr.exe create C:\test.txt "my file content"
I would suggest to use quotes even in file path as well. When you use args, its always a chance to make mistake while accessing arguments.

How to open .rtf files as text stream

I am very very novice to c# and .net and trying to understand it.
I am using solution from how to read all files inside particular folder and trying to apply in my below code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace HowToCopyTextFiles
{
class Program
{
static void Main(string[] args)
{
StringBuilder sb = new StringBuilder();
foreach (string txtName in Directory.GetFiles(#"C:\Users\Environ ment\Desktop\newfolder","*.rtf"))
{
using (StreamReader sr = new StreamReader(txtName))
{
sb.Append(sr.ReadToEnd());
sb.AppendLine();
}
}
Console.Write(sb.ToString());
Console.ReadLine();
}
}
}
The result is ok but at the end of my test file it shows environment name.
like.
this is content of first file
this is content of second file
↑My environment full name ↑My
environment full name ↑My environment full name (Yes 3 times)
I am using cs-script, Is it due to that?
While using .txt files, it is working fine. so the question is how to properly open .rtf files as text stream?
If rtf file is opened, it sometimes saves super hidden(not visible even show hidden file option) temp file as ~filename.rtf which is also read by c#.
I used code from here: C# - Get a list of files excluding those that are hidden
DirectoryInfo directory = new DirectoryInfo(#"C:\temp");
FileInfo[] files = directory.GetFiles();
var filtered = files.Where(f => !f.Attributes.HasFlag(FileAttributes.Hidden));
foreach (var f in filtered)
{
Debug.WriteLine(f);
}
This solved my problem.

Obtaining Errors on a code for loading and displaying a DICOM image in C#

There was individual, whom post a code to load and display a DICOM image in C# with the ClearCanvas Library. However, I tried t run the code and i'm receiving an error and have a missing library dll component. I would like to know where the individual obtained the library dll file ClearCanvas.Dicom.ImageViewwer.StudyManagement. I've been unable to locate that file on the internet. The code is displayed after the errors. I am grateful thanks.
Usings:
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;
using ClearCanvas.Common;
using ClearCanvas.Dicom;
using System.Windows.Media.Imaging;
using ClearCanvas.ImageViewer;
using ClearCanvas.ImageViewer.StudyManagement;
using System.Windows.Interop;
using System.Windows.Media;
This is the body:
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "DICOM Files(*.*)|*.*";
if (ofd.ShowDialog() == DialogResult.OK)
{
if (ofd.FileName.Length > 0)
{
var imagen = new DicomFile(ofd.FileName);
LocalSopDataSource DatosImagen = new LocalSopDataSource(ofd.FileName);
ImageSop imageSop = new ImageSop(DatosImagen);
IPresentationImage imagen_a_mostrar = PresentationImageFactory.Create(imageSop.Frames[1]);
int width = imageSop.Frames[1].Columns;
int height = imageSop.Frames[1].Rows;
Bitmap bmp = imagen_a_mostrar.DrawToBitmap(pictureBox1.Width, pictureBox1.Height);
pictureBox1.Image = bmp;
imageOpened = true;
}
ofd.Dispose();
}
}
In addition to referencing the proper assemblies (here... it's linked from the main page of clearcanvas.ca) I mentioned in a comment, consider employing the using keyword since OpenFileDialog implements IDisposable like so:
using(OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "DICOM Files(*.*)|*.*";
if (ofd.ShowDialog() == DialogResult.OK)
{
// rest of your code goes here
}
}
This has the benefit of calling ofd.Dispose() automatically, even if the code inside the using block throws an exception. This works for anything that implements IDisposable (so bitmaps, fonts, streams, etc.)
I posted the code actually..
These are the DLLs I used in my project:
Clearcanvas:
ClearCanvas.Common.dll
ClearCanvas.Desktop.dll
ClearCanvas.Dicom.dll
ClearCanvas.ImageViewer.Common.dll
ClearCanvas.ImageViewer.dll
ClearCanvas.Utilities.Manifest.dll
Others I also added since I was getting an error when trying to show the image..
log4net.dll
nunit.framework.dll
WindowsBase.dll
BilinearInterpolation.dll --> For this one make sure you add either the 32 or 64 bits dll depending on what's your project defaults.

Write to file skipped on first run

I am new to C# and have code that will obtain the userName from the LogIn and begin a program in the background if this is the users first time loging into the system. However, today I noticed when running the program and checking my log file that the program skips adding data to the file that is also created on the initial run. Any run after the initial run, the userName is included into the .log file and if the userName does not match what is in the .log file the file is overwritten to include the new userName. Can someone please help me figure out what happened or if I'm missing something?
Thank you in advance.
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 System.IO;
using System.Diagnostics;
namespace User
{
public partial class Form1 : Form
{
public const string dir = #"C:\Numara";
public const string path = dir + #"\Audit.log";
public const string TrackIT = #"C:\Program Files\Numara Software\Numara Track-It!\Track-It! Server\Audit32.exe";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//returns user name
//label1.Text = System.Environment.UserName.ToString();
string userName = System.Environment.UserName; //user name
if (!Directory.Exists(dir))
//directory does not exist
//create it
Directory.CreateDirectory(dir); //creates directory
//by this point directory is created
//now check file
if (!File.Exists(path))
//file does not exist, so create it
File.Create(path);
//Read data from the .log file
string line = System.IO.File.ReadAllText(path);
//if the name of the logged in user
//is the same as the user name of the text file
//then exit program
--------- the debugging stops here and skips to end the program on the first run---------
if (line == userName)
Application.Exit();
else
//clear fields and write new name to file and begin audit
{
//clears fields
using (FileStream stream = new FileStream(#"C:\Numara\Audit.log", FileMode.Create))
{
using (TextWriter writer = new StreamWriter(stream))
{
//writer.Write("");
writer.Write(userName);
}
// writes new name to file
}
StreamReader textIn =
new StreamReader(
new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read));
//begins audit
Process.Start(TrackIT, "/Q");
Application.Exit();
}
}
}
}
File.Create creates a file and returns a FileStream, so it does not close it. Next you want to read it, but it is locked by the File.Create. So exception appears which is not handled and your application quits. Second times the file is already created, so it skips creating and locking it.
So you need to close the file by putting it into using block:
using (File.Create(path))
{
}
Also, you should put all the stuff into try catch blocks to handle IO exceptions - you can never know if one occurs.
You are doing battle with a nasty bug in the 64-bit debugger. Any exceptions in the Load event are swallowed without a diagnostic. The workaround is Project + Properties, Compile tab, Platform Target = x86. Now the debugger will stop at the exception. Fixing it is your next task.
Just in case: avoid catching exceptions that you shouldn't handle. Using try/catch is not typically a real solution. Just a band-aid that spackles the injury.
I would check the value of the userName variable and the line variable on that first run. You could output that to your log file also. My guess is that if the System.Environment.Username variable is empty, you end up in this case where you simply exit.
Another possibility is that you're not properly handling an exception raised from File.Create(). According to the online docs for File.Create(): http://msdn.microsoft.com/en-us/library/aa328775(v=vs.71).aspx there are 7 different exceptions that are thrown. Try catching and logging these exceptions to see if this could be the case.

Categories

Resources