I want to open a MS Word document from my program. At the moment, it can find it when in designer mode but when i publish my program it can't find the file. I believe I need to embed it into my program but I don't know how to do this. This is my current code to open the document:
System.Diagnostics.Process.Start("Manual.docx");
I think the Word document needs to be embedded into the resources of the .exe but i don't know how to to do this.
Can anyone help with some suggestions?
Aaron is pretty right on adding an embedded resource. Do the following to access an embedded resource:
Assembly thisAssembly;
thisAssembly = Assembly.GetExecutingAssembly();
Stream someStream;
someStream = thisAssembly.GetManifestResourceStream("Namespace.Resources.FilenameWithExt");
More info here:
How to embed and access resources by using Visual C#
Edit: Now to actually run the file you will need to copy the file in some temp dir. You can use the following function to save the stream.
public void SaveStreamToFile(string fileFullPath, Stream stream)
{
if (stream.Length == 0) return;
// Create a FileStream object to write a stream to a file
using (FileStream fileStream = System.IO.File.Create(fileFullPath, (int)stream.Length))
{
// Fill the bytes[] array with the stream data
byte[] bytesInStream = new byte[stream.Length];
stream.Read(bytesInStream, 0, (int)bytesInStream.Length);
// Use FileStream object to write to the specified file
fileStream.Write(bytesInStream, 0, bytesInStream.Length);
}
}
Right click the folder where you want to store the file within the Solution and choose Add -> Existing Item.
Once you add the file you can change the Build Action of the file within your project to be an Embedded Resource, versus a Resource. This can be done by going to the Properties within VS of the file and modifying the Build Action property.
Just include it to your project (add existing item) and from the menu that opens, select all files and select your word document. Also Copy the document into your Bin/Debug folder. If you are using an installer, include the document in the installer and it should work.
Related
I've added a test.zip to a C# project by creating a Resource1.resx and dragged to the resx tab. It is now visible in the Solution Explorer as a child of Resources.
When the program runs, I'd like to move it from the .exe to a location on the computer like My Documents.
I've a feeling I need to convert the resource to a memory stream before I can write it to file but I'm not sure how to access the file as resource or how to convert it.
I think the following extracts the resource object (then again, it doesn't error no matter what the first param is) but I'm not sure how to proceed:
var resource = new ResourceManager("test", Assembly.GetExecutingAssembly());
Since you activate the resources you have already a ResourceManager.Just use GetObject method,get the bytes of your file and write the them to a new file with File.WriteAllBytes:
var bytes = Properties.Resources.ResourceManager.GetObject("resourceName") as byte[];
File.WriteAllBytes("newFile.zip", bytes);
You should use Assembly.GetManifestResourceStream.
using (Stream x = Assembly.GetExecutingAssembly().GetManifestResourceStream("test"))
{
...
}
Reference to MSDN.
I'm working with print jobs using PrintSystemJobInfo and this class doesn't have the path of the file (print job). So, I was wondering if there is a class where I can use the filename that is open (in memory) and this class return the full path. This file opened could be .doc, .pdf, .xls, .txt, and so on.
Please, someone can point me to the right direction or have an idea... it would be very helpful...
The only way for you to find open file handles is to use the NtQuerySystemInformation call. Here is a project that has this done as an explorer context menu. In this guy's case, he looks for files open in a specific folder.
You would then have to match the file name to the file you have in your print job.
By the way, this is not C# but you can wrap and call the same calls he is using. The rest is really up to you to figure out. ;)
Assuming you have a Stream object that is a FileStream then just do a cast and interrogation:
Stream str = printJob.JobStream;
FileStream fileStream = str as FileStream
if( fileStream != null ) {
String fileName = fileStream.Name;
}
I have a project that uses an Access DB file for reference tables. This is to be used at work, but I am developing it at home. Up until now, I've simply run the debugger in VS2010, then copied the relevant class files, exe, etc from the /bin folder to a flash drive, and it's worked fine. But with the DB added in, it suddenly crashes on launch.
I know the problem is the file location of the DB file. Originally the Build Action of the DB was sent to Content. I have changed it to Embedded Resource, which as far as I understand means it will be part of the exe file now.
Am I correct in this? If not, what option do I need to select to have the DB become just a compiled part of the exe, or one of the other dll's?
If the db file is embedded, you can't access it to add/removes rows etc.
Why did you change the build action to Embedded Resource ? It'll be better to put as Content, so the db is a separate file than the exe (but still in the same directory), and then build the path to the db file (i.e. using Application.StartupPath).
Anyway, if you want to set it as Embedded you'll need to extract the db at runtime and store it somewhere before using it.
Here is a method that can extract a file from the embedded resources (of course you'll need to change the filename, or pass it as argument):
private void ExtractFromAssembly()
{
string strPath = Application.LocalUserAppDataPath + "\\MyFile.db";
if (File.Exists(strPath)) return; // already exist, don't overwrite
Assembly assembly = Assembly.GetExecutingAssembly();
//In the next line you should provide NameSpace.FileName.Extension that you have embedded
var input = assembly.GetManifestResourceStream("MyFile.db");
var output = File.Open(strPath, FileMode.CreateNew);
CopyStream(input, output);
input.Dispose();
output.Dispose();
System.Diagnostics.Process.Start(strPath);
}
private void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[32768];
while (true)
{
int read = input.Read(buffer, 0, buffer.Length);
if (read <= 0)
return;
output.Write(buffer, 0, read);
}
}
The file will be copied in the local application path, in the user directory. It'll be done the first time the app is started, because otherwise the db file will be overwritten each time the application start (overwritten with the clean db package in the exe)
I have a PDF file that I have imported in as a resource into my project. The file is a help document so I want to be able to include it with every deployment. I want to be able to open this file at the click of a button.
I have set the build action to "Embedd Resource". So now I want to be able to open it. However, When I try accessing the resource - My.Resources.HelpFile - it is a byte array. How would I go about opening this if I know that the end-user has a program suitable to opening PDF documents?
If I missed a previous question please point me to the right direction. I have found several questions about opening a PDF within an application, but I don't care if Adobe Reader opens seperately.
Check this out easy to open pdf file from resource.
private void btnHelp_Click(object sender, EventArgs e)
{
String openPDFFile = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + #"\HelpDoc.pdf";//PDF DOc name
System.IO.File.WriteAllBytes(openPDFFile, global::ProjectName.Properties.Resources.resourcePdfFileName);//the resource automatically creates
System.Diagnostics.Process.Start(openPDFFile);
}
Create a new Process:
string path = Path.Combine(Directory.GetCurrentDirectory(), "PDF-FILE.pdf");
Process P = new Process {
StartInfo = {FileName = "AcroRd32.exe", Arguments = path}
};
P.Start();
In order for this to work, the Visual Studio setting Copy to Output Directory has to be set to Copy Always for the PDF file.
If the only point of the PDF is to be opened by a PDF reader, don't embed it as a resource. Instead, have your installation copy it to a reasonable place (you could put it where the EXE is located), and run it from there. No point in copying it over and over again.
"ReferenceGuide" is the name of the pdf file that i added to my resources.
using System.IO;
using System.Diagnostics;
private void OpenPdfButtonClick(object sender, EventArgs e)
{
//Convert The resource Data into Byte[]
byte[] PDF = Properties.Resources.ReferenceGuide;
MemoryStream ms = new MemoryStream(PDF);
//Create PDF File From Binary of resources folders helpFile.pdf
FileStream f = new FileStream("helpFile.pdf", FileMode.OpenOrCreate);
//Write Bytes into Our Created helpFile.pdf
ms.WriteTo(f);
f.Close();
ms.Close();
// Finally Show the Created PDF from resources
Process.Start("helpFile.pdf");
}
File.Create("temp path");
File.WriteAllBytes("temp path", Resource.PDFFile)
You need to convert the resource into format acceptable for the program supposed to consume your file.
One way of doing this is to write the content of the resource to a file (a temp file) and then launch the program pointing it to the file.
Whether it is possible to feed the resource directly into the program depends on the program. I am not sure if it can be done with the Adobe Reader.
To write the resource content to a file you can create an instance of the MemoryStream class and pass your byte array to its constructor
This should help - I use this code frequently to open various executable, documents, etc... which I have embedded as a resource.
private void button1_Click(object sender, EventArgs e)
{
string openPDFfile = #"c:\temp\pdfName.pdf";
ExtractResource("WindowsFormsApplication1.pdfName.pdf", openPDFfile);
Process.Start(openPDFfile);
}
void ExtractResource( string resource, string path )
{
Stream stream = GetType().Assembly.GetManifestResourceStream( resource );
byte[] bytes = new byte[(int)stream.Length];
stream.Read( bytes, 0, bytes.Length );
File.WriteAllBytes( path, bytes );
}
//create a temporal file
string file = Path.GetTempFileName() + ".pdf";
//write to file
File.WriteAllBytes(file, Properties.Resources.PDF_DOCUMENT);
//open with default viewer
System.Diagnostics.Process.Start(file);
It is actually useful for me to store some files in EXE to copy to selected location.
I'm generating HTML and JS files and need to copy some CSS, JS and GIFs.
Snippet
System.IO.File.WriteAllBytes(#"C:\MyFile.bin", ProjectNamespace.Properties.Resources.MyFile);
doesn't work for me!
On "WriteAllBytes" it says:
"cannot convert from 'System.Drawing.Bitmap' to 'byte[]'"
for image and
"cannot convert from 'string' to 'byte[]'"
for text file.
Help!
UPDATE: Solved below.
Add the files you want to your solution and then set their Build Action property to Embedded Resource. This will embed the file into your exe. (msdn)
Then you just need to write the code to write the file out to disk when the exe is executed.
Something like:
File.Copy("resource.bmp", #"C:\MyFile.bin");
Replace resource.bmp with your file name.
Addendum:
If you keep the file in a sub-folder in your solution you need to make the sub-folder part of the path to resource.bmp. Eg:
File.Copy(#"NewFolder1\resource.bmp", #"C:\MyFile.bin");
Also, you may need to set the Copy To Output Directory property to Copy Always or Copy If Newer.
I assume you added the files through the Project Properties window. That does not allow you to add an arbitrary file but it does support TextFiles, Bitmaps and so on.
For an embedded TextFile, use
File.WriteAllText(#"C:\MyFile.bin", Properties.Resources.TextFile1);
For an Image, use
Properties.Resources.Image1.Save(#"C:\MyFile.bin");
You can embed binary files in a .resx file. Put them in the Files section (it looks like you used the Images section instead). It should be accessible as an array of bytes if your .resx file generates a .Designer.cs file.
File.WriteAllBytes(#"C:\foobar.exe", Properties.Resources.foobar);
Add files to project resources and set their "Build Action" as "Embedded Resource".
Now extract any file (text or binary) using this snippet:
WriteResourceToFile("Project_Namespace.Resources.filename_as_in_resources.extension", "extractedfile.txt");
public static void WriteResourceToFile(string resourceName, string fileName)
{
int bufferSize = 4096; // set 4KB buffer
byte[] buffer = new byte[bufferSize];
using (Stream input = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
using (Stream output = new FileStream(fileName, FileMode.Create))
{
int byteCount = input.Read(buffer, 0, bufferSize);
while (byteCount > 0)
{
output.Write(buffer, 0, byteCount);
byteCount = input.Read(buffer, 0, bufferSize);
}
}
}
Don't know how deep is it correct according to this article: http://www.yoda.arachsys.com/csharp/readbinary.html
but it works.