this is my scenario: I have an executable file that convert html files to pdf.
This exe work only if you start it from its folder.
Example: the exe is in C:\HtmlToPdf, so, in the prompt I will do this:
C:\> cd HtmlToPdf
C:\HtmlToPdf> htmltopdf.exe htmlFile pdfFile
So, there is a way to do this in c#? Because I tried this:
FileInfo htmlInfo = new FileInfo(executablePath + #"\" + filename);
var procInfo = new ProcessStartInfo("wkhtmltopdf.exe",htmlInfo.FullName + " " + htmlInfo.FullName.Replace(".html",".pdf"));
procInfo.WorkingDirectory=executablePath;
procInfo.UseShellExecute = false;
Process.Start(procInfo);
But it doesn't work.
wkhtmltopdf's documentation/wiki states that it will struggle to find a file if you use its full path. You need to append file:/// to the beginning of the file name
Note that on Windows, you can't use absolute path names with drives for HTML files at the moment:
wkhtmltopdf d:\temp\x.html x.pdf
will fail. You need to rather use file:/// URLs:
wkhtmltopdf file:///d:/tmp/x.html x.pdf
This answer may help in the appending
From where you are calling the EXE .. .whether its Windows Form application or Webforms....
If its windows forms it will work
else
if its Webforms like asp.net you have to change the properties of IIS Server to start the exe
Because due to some security reasons microsoft will not allow you to start the process class from IIS server... but the same code will work from Visualstudio ..
Here is my code
To get Current Exe Executable path
string sCurrentPAth = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
Process.Start(#"E:\Debug\MyExe.exe", "arg1 arg2 arg3");
Its Working Correctly .....
Related
I have been looking for a little while now and am not finding much help via MSDN resources and others.
My predicament is simple: my app needs a base directory to the Downloads folder. I am aware of the DownloadsFolder class however that is not suiting my needs currently.
How do I get the current user's Download folder path in a Windows Universal App?
Use Windows.Storage.UserDataPaths to get the path of user's download folder.
string downloadsPath = UserDataPaths.GetDefault().Downloads;
This method is introduced in build 16232, so clients with RS3(1709) or later will be able to run it.
You shouldn't obtain downloads folder path using LocalFolder, which might result in wrong folder when the user changed the default location for it.
System.Environment.ExpandEnvironmentVariables("%userprofile%/downloads/")
Is that what you need?
string localfolder = ApplicationData.Current.LocalFolder.Path;
var array = localfolder.Split('\\');
var username = array[2];
string downloads = #"C:\Users\" + username + #"\Downloads";
This will result
C:\Users\username\Downloads
The DownloadsFolder for an app now defaults to a folder withing the user's Downloads directory named after the app name (in actual fact the app name folder is simply a link to a folder named after the Package Family Name)
To get the folder name, I used the following hack (vb) to first create a dummy file in the UWP app's DownloadsFolder then using .NET code to get the directory name, and finally deleting the dummy file.
Dim o As StorageFile = Await DownloadsFolder.CreateFileAsync("dummy.txt", CreationCollisionOption.GenerateUniqueName)
Dim dirName Ss String = Path.GetDirectoryName(o.Path)
Await o.DeleteAsync(StorageDeleteOption.PermanentDelete)
I copied over some code from a test app:
const string sdfPath = #"C:\WebAPIClient\WebAPIClient\bin\Debug\DBPlatypusCompactDB.sdf";
string dataSource = string.Format("Data Source={0}", sdfPath);
int countAdded = 0;
if (!File.Exists(sdfPath))
. . .
...which works fine there; but on trying to convert it for use in the project that will run on the Windows CE device:
const string sdfPath = #"Computer\WindowsCE\\\Program Files\hhs\DBPlatypusCompactDB.sdf";
. . .
...(this is the path I copied from Windows Explorer (the folder to which the exe is deployed, which has no subfolders)), I get "path not found" or "path not valid" or something similar.
How am I to designate the path?
It's not really clear what you're trying to do, so here are some general pointers:
Windows CE doesn't understand relative paths. Period. So all paths must start with a backslash (\) character.
"Computer" is highly unlikely to be part of the path on your device. Use Explorer on the device ansd look at the path there. What you're after is probably something like \Program Files\hhs\mydatabase.sdf
Desktop paths to a device are not actual paths. They are shell plug-in trickery. A path on the PC like My Device\Program Files\foo.bar is not a path resolvable by any File APIs on the desktop. If you want to access a device file from a PC app, you must use something like RAPI to pull the file locally, then use the local copy
if you want to run on device use this code:
const string sdfPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase + #"\FolderName\Filename.*"
but, you need to copy FolderName to device on Program File path see images folder example:
Connect to your device
Show images folder example
I created a PDF webapp where users are able to generate various type of PDF on both the computer and mobile phone. However, i run my program on a localhost and this is how i save my PDF based on my computer's file directory
var output = new FileStream(Path.Combine("C:\\Users\\apr13mpsip\\Downloads", filename), FileMode.Create);
However, when i publish my webapp onto azure, i wasn't able to download from both my computer and mobile phone. Therefore i believe that it could be due to my default file directory.
Hence i would like to ask how to do a default file directory for all computer and mobile phone?
Or could it be i left out something that is necessary when the webapp is published online
Thanks.
PS : I hardcoded a default file path in order for me to test my application on a localhost to ensure a perfect working condition. Therefore i'm finding a way to find a default common file directory for all mobile/computer users when they attempt to download the PDF instead of my usual hard-coded file path
UPDATE
I tried using the method Server.MapPath but receive some error.
var doc1 = new Document();
var filename = Server.MapPath("~/pdf") + "MyTestPDF" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".pdf";
// var output = new FileStream(Path.Combine("C:\\Users\\apr13mpsip\\Downloads", filename), FileMode.Create);
//iTextSharp.text.pdf.PdfWriter.GetInstance(doc1, output);
using (var output = File.Create(filename))
{
iTextSharp.text.pdf.PdfWriter.GetInstance(doc1, output);
}
doc1.Open();
This is the error i received
ObjectDisposedException was unhandled by user code
Cannot access a closed file.
When you write a Web Application you shall never use hard coded paths, and the last place where you should save files is C:\Users !! It does not matter whether this is Azure or not. It is general rule for any kind of web applications!
In your case I suggest that you create a folder within your application named pdf or something like that and save files there with the following code:
var fileName = Server.MapPath("~/pdf") + filename;
using (var output = File.Create(fileName) )
{
// do what you want with that stream
// usually generate the file and send to the end user
}
However there is even more efficient way. Use the Response.OutputStream and write the resulted PDF directly to the response. Will save you a lot of space on the local server, and the logic to delete unused generated files.
I am working on a windows service c# program.
I need to use a file. Here is my code
const string mail_file_path = #"template\mailbody.html";
But according to my log, there is an error like this:
Error: Could not find a part of the path 'C:\Windows\system32\template\mailbody.html'.
I use the app.configuration to use another file
<add key="TimeStampFilePath" value="timestamp.ini" />
StreamReader sr = new StreamReader(ConfigurationManager.AppSettings["TimeStampFilePath"]);
But I can't read the file.
When I run this project as a simple windows console project, it works. But after I run it using windows service mode, the two problems appear.
You could try:
// dir is path where your service EXE is running
string dir = Path.GetDirectoryName(
Assembly.GetExecutingAssembly().Location);
// mail_file_path is where you need to search
string mail_file_path = Path.Combine(dir , #"\template\mailbody.html");
Take my answer as an integration to #CharithJ's post, which is definitely correct!!
If you have got template\mailbody.html in the same directory where the service exe resides. Try something like below and see. You could find the folder where the windows service .exe resides.
string mail_file_path = System.Reflection.Assembly.GetEntryAssembly().Location +
"\template\mailbody.html";
Or this also can help AppDomain.CurrentDomain.BaseDirectory
I found a way to solve the problem, thanks to the suggestion from #Macro. I get the windows service mapping directory using REGISTER API, then setting the working directory the same with it. Then I can use the relative path to get the file I need.
In my application, after the user logs in I set a few picturebox/button/etc images and do some scaling on them and whatnot. I use relative paths for example:
#".\Images\SomeImage.png"
It works fine when the application is launched directly, but if you try to run it via another application:
Process process = new Process();
process.StartInfo.FileName = networkPath;
process.Start();
It dies and comes up with a file not found error, because it cannot locate the images. It also does this if I try to launch it via the command prompt. The executable is stored on a network drive. Why won't the relative path work in this situation? I can just go ahead and hard code the full path but that makes me feel dirty... Any thoughts?
This is because the working directory is different - by default when starting a new process the working directory for the new process is set to the working directory of the existing process (which will in turn probably be the directory that existing application is contained within).
Normally your application will be run with the working directory as the directory that the executable is contained in - this is the default when creating a new shortcut for example (you can see this in the shortcut properties under the "Start in" field.
When your application is run from the command prompt or from another application however the working directory is changed and the relative paths are resolved to a completely different directory.
You can either change the calling application to se the WorkingDirectory property of the new process to the value it expects, however the proper way of fixing this it to modify your application so that it uses absolute paths based on the path to the executable. Assembly.GetExecutingAssembly().Location can be used to get the path to the executable being run and so the following code should do the trick:
static string GetAbsolutePathFromRelative(string RelativePath)
{
string directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string absolutePath = Path.Combine(directory, RelativePath);
// This final call is to stop paths like "C:\Dir\..\OtherDir\file.txt" being returned
return Path.GetFullPath(absolutePath);
}
You need to set the Process.WorkingDirectory property to the correct path.
The path you posted:
#".\Images\SomeImage.png"
Is not a network path (it is not UNC or using a mapped drive).