Display Image in Crystal reports Using URL - c#

I want to show image in a crystal report.
Scenario is something like this.
I have a database where my path of an image is persisting.
eg ftp://Images/1.jpg
Now i want to repeat this image in a crystal report.
When i fills my datatable it shows me complete url. When i displays this field in GridView i uses imageBox to display my image and it works for me very fine.
But when i tries to do the same with crystal reports, it starts me showing image path as it is. Now here instead of path i want an image to be displayed.

OK, so the trail of tears to show images in CR report over the web is as follows:
1) The following is assumed:
a) CR 2008 aka CR 12. I know not about earlier versions, but XIR2 (11.5) may work.
b) Web display of pictures in reports is desired, with local workstation development and preview
c) IIS, ASP.NET application, .NET 4.0
d) Crystal Reports installed correctly ( that is an entirely different discussion, but suffice it to say, you better have a folder named aspnet_client with subdirectories as follows:
**system_web
4_0_30319
crystalreportviewers12**
etc.
that is parallel to the location of the web application. There's a lot more - but not here though...
e) Images are like photos or whatever but are reasonably sized and not too huge bytes-wise.
f) Thumbnails for each image exist, or a default thumbnail file is available.
g) They are JPG, PNG, or BMP images. Otherwise, you are out of luck AFAICT. If they are documents like Word, PDF, etc. which you wish to show in the same list, you will need a thumbnail for those too. But let's stay on the image topic...
h) You have images organized into a folder hierarchy on your web server, or accessible to your web server, but in any event, accessible to the website. Let's assume they are all under a main location D:\MyDocuments
I HAVE NOT TRIED THIS REFERRING TO AN FTP SITE LIKE THE ORIGINAL QUESTION BUT I DOUBT IT WILL WORK.
2) You need a database table or other sort of repository accessible to the webserver to register your images. The DB format is flexible, but we will assume it is a list keyed to your primary domain of interest, where you have 0:N images per main item, say, pictures of a residence, or pictures of a bridge, or pictures of a home inspection. This table has either a full path to your files, or a relative path, or a folder location plus a dedicated file name column. Whatever, but they have to make a file path like:
D:\MyDocuments\folderA\folder1\area51\whatever\myfile.png
so the database holds the whole thing , or part of it, or the bits, or whatever.
3) The root folder is D:\MyDocuments when viewing reports locally/standalone/not with a browser. This is an arbitrary name but keep track of it for now.
4) You register that root folder so CR can find it. This can either be hard-wired into your reports (bad) or looked up from an INI file (ummm, OK) or in a database field (why not,since you are registering your images anyway?) or passed as a parameter to your reports that want to show pictures or document links (simple, but what happens when you deploy to some other file system?)
5) In your report that shows the pictures, and I am assuming here N / item of interest as described in (2) above, you have a picture inserted with the CR designer. Link it to some really bogus picture or a default image so you can tell if you are resolving the file names....
6) The picture thumbnail's path is retrieved from the database and assembled as necessary, with BACK SLASHES, into a file name. It will be stored in a Shared StringVar FullQualifiedThumbnailFileName (let's say) in the report and consists of the document root, which you made available to the report in step (4) and stored in a dedicated Shared StringVar DocRoot (let's say) PLUS the calculated file name. So formula field FullyQualifiedThumbnailFileName looks like:
{#DocRoot} & FolderLocationFromDB & ThumbnailFileNameFromDB or in real life:
D:\MyDocuments\folderA\folder1\area51\whatever\tn_myfile.png
7) So now you have a thumbnail file name. Drop it anywhere on your draft report so you can see what it is resolving too during design. Do the exact same thing to refer to the REAL file name and make a variable called FullyQualifiedThumbnailFileName. It should be openable with a picture viewer if it has been constructed correctly. Drop it somewhere too so you can read it and use it to test.
8) Right-click on the picture object on the report, pick Format Graphic, click the picture tab, and open the formula icon for the picture location.
Before you start whining at me please look at the assumptions at the top - I have no clue which earlier versions of CR support this, or if they do it differently.
Then, in the formula editor, enter the following:
{#FullQualifiedThumbnailFileName} which you created just a minute ago. Your thumbnail is a Windows DOS path to a local file name on the webserver or your development workstation.
9) Now add a parameter to your report, or make a formula variable, or whatever, that consists by default of the string "file://". This will be REPLACED at runtime with the httpContext.Current.Session application root but we'll get to that in a minute. I guess you could have done this earlier.... Name this WebURLRoot
10) Create a formula field called txtImageURL Anyway, the name is up to you but guess what goes here? Something like the following:
if lowercase( {#WebURLRoot} ) = "file://" THEN
{#WebURLRoot} &
REPLACE( {#txtDocumentFileFullyQualifiedName},"/","\")
else
URLENCODE( {#WebURLRoot} &
REPLACE(
{*DocumentFileNameFromYourSource*}
,"\","/") )
The appending of file name DocumentFileNameFromYourSource to WebURLRoot works for me because I have relative paths in my situation that do NOT include the DocRoot. Your situation may be different. In any event, in standalone mode, this variable should resolve to:
file://D:\MyDocuments\folderA\folder1\area51\whatever\myfile.png
where this is not a thumbnail. At runtime on the web, it should resolve to:
http://somewebhost/website/folderA/folder1/area51/whatever/myfile.png
because we are going to supply http://localhost/website to the variable WebURLRoot somehow.I did it using a parameter passed from the web application. It could be looked up or hardwired but remember, what happens if the website gets relocated?
Put {#txtImageURL} into the hyperlink calculated file name formula, and click the option to indicate that it is coming from a website on the internet AKA your local development server or whatever.
In standalone mode, the file strings in txtImageURL have backslashes. At runtime, they are set to forward slashes for the full file name. The URLEncode function from Crystal makes them nice for web purposes.
Again drop txtImageURL onto your development surface until it is straight.
11) You now have a CR RPT with
a) A variable holding the Windows root of your documents tree C:\MyDocuments, which you supplied to the report by whatever means. I store it in the database my application connects to.
b) A variable holding the Window path to your thumbnail, constructed from the thumbnail name in the database plus the document root
c) A variable holding the Windows path to your real file name, again constructed from the actual file name in the database plus the document root
d) A web site URL stem which is file:// during development and http://localhost/website/ at runtime for the website. You are passing this
e) A working URL for the image file combining the web site URL stem with the actual file.
Good so far? Grab a beer. Maybe 2.
C# changes
1) OK, so we need to tweak our world to pass the web site URL stem to a report at runtime as a parameter. You cannot do this over the web using the Crystal Reports Viewer. Assuming you have followed one of the many examples available for how to load, parameterize and show a report from a web application, and I think you can find these with Google, make sure you do this in your application somewhere. I located mine in Global.asax.cs in the Session_Start event which seems highly reasonable according to the authoer... Please note that credit is due to the referenced URL personage... :
// so Crystal can receive the APP_Path as an argument
// Code that runs when a new session is started
// http://aquesthosting.headtreez.com/doc/d9ccf4d8-1873-469e-9dca-815e5854b963
string appPath = System.Web.HttpContext.Current.Request.ApplicationPath.ToLower();
if (appPath == "/") //a site
appPath = "/";
else if (!appPath.EndsWith(#"/")) //a virtual directory i.e. in a subfolder
appPath += #"/";
Session["APP_Path"] = appPath; //stores the value to a session variable for us to use
2) Now where you create the parameters for your report, make sure to pass Session["APP_Path"] as a parameter something like this:
// START CHANGE
// this next check seems unlikely
if(! (HttpContext.Current.Session == null))
{
// pass HttpContext.Current.Session["APP_Path"].ToString() as a parameter
if (!(String.IsNullOrEmpty(HttpContext.Current.Session["APP_Path"].ToString())))// set in Global.asax.cs Start_Session
exporter.Arguments.Add(exporter.Arguments.Count, HttpContext.Current.Session["APP_Path"].ToString()); // to last parameter position
else
exporter.Arguments.Add(exporter.Arguments.Count, String.Empty); // or nothing to last parameter position
// end change
}
where exporter.Arguments holds the parameters for my reports. Your situation will doubtlessly be different. One somewhat important thing is to put this parameter either ALWAYS FIRST or ALWAYS LAST, such that other parameters are not screwed up by it. Use the very same order for parameters in the report itself. The parameters apparently associate values by name anyway but I think mish-mashing them is a bad idea and ultimately confusing.
3) So now you run your reports standalone, and when prompted for the web site URL stem you enter file://. When the same exact report is run over the web, the application sends it whatever the website stem is but something like http://localhost/website/ .
GOTCHAS:
1) During development of this, show your variables on your reports. Make sure that for the thumbnails you are using server-relative but full Windows/DOS paths always, and for the pictures, either full Windows/DOS paths during development prepended with file://
You can always hide them before production.
2) Watch out for too many slashes etc. It is easy to end up with a double slash which screws up the URLs...
3) Remember that formulas are evaluated in some sort of mystical sequence by Crystal but I understand that the Page Header is processed before the detail. I put ALL my common variables i.e. DocRoot and WebSiteRootURL there in the Page Header (or even the Report Header since they do not change), so they are quantified first, and the detail band can use them.
4) I delegated all the picture showing and listing to an embedded subreport. It shares the variables it needs using a Shared StringVar xyz approach. It is all a bit squirrelly but basically the subreport always gets its value from the container report for the common stuff (see comment 3 right above). For laying out that subreport, I made an even tinier subreport to serve as the holder for the common variables so I would not have to run the whole monstrosity.
5) These 'variable holder'reports cannot be suppressed or the values do not appear to resolve. So make them extremely tiny and borderless, then squish up the page headers or whatever to hide them. I guess the text and background could be set identical as well to further cloak them but don't do that until you are done fiddling with the layout etc. or you will have to graze around to find the itty-bitty subreport. They are your local memory variables.
6) Image/document/linked files in standalone MUST use conventional DOS/Windows file name paths (no forward slashes). These can resolve for the website but to make a hyperlink, the slashes gotta go forward as far as I can tell so assume you will have to flip-flop.
7) As a side note, I was able to relocate my documents out of the website hierarchy during development by using Junction Magic to remap ~/MyDocuments to D:\MyDocuments etc.. The web server does not appear to care that it is actually traversing D:\MyDocuments but thinks that it is in a subfolder of the website. HOWEVER, you may have to use a Virtual Directory approach - be forewarned. Or, store the documents right under the website but somehow that seems klutzy.
8) Did I mention permission problems? No, but they might bite you. Make sure the IIS_IUSR and whatever can access the files/folders etc.
9) Shouldn't this have all been much easier? Oh well, thank you anyway SAP...
NEWS BLAST -
so apparently the Request object also holds the web site URL stem. Use that if you don't want to go the route of a global.
Also, I may not have explicitly stated it, but the CR OLE object only understands Windows... not unix file name conventions. As a further consideration, path lengths have to conform.
Finally, when I show file names on the web page, I cloak both the DOS/Windows root and the website stem and just show the relative path e.g. ~/Folder/Folder/File.png so that it is not too obvious how the documents are arranged on the website - probably needlessly paranoid but also has the benefit that if the website moves users don't get bewildered.
Questions may or may not get answers. Have fun.

Here you go... (tested with VS 2013) - Working !!!
1) Ad an image to the report using insert->picture
2) Right click on image -> format object ->picture
3) Change the formula of the graphic location
ex-
"E:\tmp\wrk\s1.jpg"
You can change the path and the file name according to your requirement and conditions using the formula builder

The main problem is CrystalImageHandler.aspxonly works for the root folder (I mean: for c:\inetpub\wwwroot) So there are 2 options:
From the ISS Manager change Default Web Site-> Advanced Settings->Physical Route from %SystemDrive%\inetpub\wwwrootto YourFolderName
Move your files to %SystemDrive%\inetpub\wwwroot
So far, I found this solution. Hope it helps.

I know that if you are using the Crystal Reports included with Visual Studio, this is not supported. It will display images stored in a db field, but not from a url.
I think (but do not know for sure) that no version of Crystal supports the ftp protocol for displaying images.

Related

Upload functionality not working. ASP.NET Page

so basically I am trying to piggy-back from this article https://www.c-sharpcorner.com/UploadFile/5357ed/importingreadingexporting-of-csv-file-in-Asp-Net/ so I can add upload functionality into my asp.net page and then customized my gridview to something else. Mainly, I have followed the same code and gave it a run to see if everything is fine but I am getting an error with the file path in btn_import_Click. It blows because it cannot find the directory. which is line 85 from the example.
"System.IO.DirectoryNotFoundException: 'Could not find a part of the path 'C:\inetpub\wwwroot\dir\dir\upload'.'"
I would really wish it would point to the physical location of the actual file since my users will have different machines and we all won't be using the same machine nor directories when they would have that .csv file.
If you guys could shine a light I would really appreciate it. I have done this in Java with no problem but I am having a hard time with this ASP.NET Project. Thank you in advance!
Chiriqui
I am confused here.
that file path name is the web server path name. So some web server being hosted some place?
That has ZERO to do with the users local file system.
You cannot get, see, determine ANY path names on the client side computer running the browser.
When you up-load a file, you ONLY get the file name.
You cannot grab, get, determine, OR EVEN SET the file name from the client side.
I mean, if you hit my web site to view a cat picture?
The while you looking at the cat picture, my code can't start looking around on YOUR computer, and say grab a file called passwords.txt, or some files called my banking files.
When you up-load, then you NOW have the file, and can save it any place you want on that web server computer. But, as such, these path names, and even the file name you choose to use have ZERO to do with any folder name, or file name on the client computer side. the web works this way for reasons of security.
You have ZERO knowledge of path names, file names, or ANYTHING that is on the client side computer.
So a file upload control?
It lets the USER pick the file - not you, not your code behind, and not your JavaScript code. You can NEVER control, set, get, change, or even in code determine the drive letter, the folder, or even the file name. The user client side MUST and will choose the file. It is then up-loaded.
At that point, you are free to save the file in any folder. In that example, they used a folder called "upload". You can create and name and choose ANY folder name you want in place of the name "upload" folder. However, that folder is on the server side, and has ZERO to do with ANY name, and ANY folder on the client side.
You NEVER get passed the folder name when the user up-loads a file. You ONLY get a file name, and the file data. Nothing more, and nothing less is EVER set to your sever.
And what happens if they are using a Android phone, or a iPhone? They don't even have standard windows path names.
Now, the way this works might often be a bit confusing, since during development, your ONE computer is running both your code, has your file system, and has the web server all running on one computer.
However, once you publish that web site, then the code, the web server, and the folders and files used can ONLY be from the web server side. You have no information about the client side file system. Not even path names can be used, or even known about.
You get a file name, and you get the file data. At that point, you can save to any folder on your web server. but as such, these file names, path names, folder names are 100% under your control, and the end user has ZERO clue about what folders you as the developer choose to use for your web server.
So, the path name of "uploads" is NOT on the client side computer, but is a path name ONLY on the web server side of things.
So, it is thus confusing you state this:
the actual file since my users will have different machines and we all won't be using the same machine nor directories when they would have that .csv file.
But you can't know that location in your web server code. The user has to go and select that file, and the up-load to YOUR computer running your web server. Where you decide to save that file is YOUR choice, and not the end user choice.
You can NEVER look at, see, or know what folders the end user has. The ONLY task the end user is allowed with file-upload is to select a file on THEIR computer. However, when they do that, and up-load?
Then on your code behind and web server side of things?
You ONLY get a file name (no path information), and you ONLY get the file data. You can't change even the file name they select. After your server and code gets that file, then you can save the file into any folder on the web server. And you can even change the name of the file you save.
But, you can't change what file they selected, and you can't change were it comes from, and you can't even in JavaScript change or touch or modify the file the user chooses. As I stated, this is for reasons of security.
You have ZERO information about where the file was located. The ONLY information you get is a file name, and the file data. Zero additional information about that file the user picked can be had, or even determined by you.
You don't have ANY knowledge of the file path names, and folder names used client side. The only task a user is allowed is to pick a file. When the file picker is launched in the browser, the user (not you) can select a file from ANY folder. When they select that file, then the file name and data is sent to the server. But NOT the path name - only the file and data.
You have zero knowledge about the users path names. And your code and assumptions thus have to be based on this simple fact and limitation.
Edit: upload a file, process to grid
Ok, so all we doing here is upload a file (csv), and then we process each row of the file, and then we display it say in a gridview.
We thus assume we have a folder in our project called UpLoadFiles.
So, the markup on the page could be this
A FileUpLoad control.
A button to up-load the selected file, and then process to grid
A gridview control.
So, say this markup:
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="cmdUpLoad" runat="server" Text="Process csv" CssClass="btn" OnClick="cmdUpLoad_Click"/>
<asp:GridView ID="GridView1" runat="server" CssClass="table"></asp:GridView>
Ok, so user selects file with Fileupload, and hits the button.
our code could be this:
We save the file (to folder UpLoadFiles).
We then convert the csv file to a datatable.
We then process some rows. In this example, we take any City column, and and Province column that is missing a value - and toss in our text.
We then send to the above grid viewe.
The code for the button thus looks like this:
-- we used the MicrosoftVisual basic csv parser
So, set a reference to this:
And now then
using Microsoft.VisualBasic.FileIO;
using System.Data;
Ok, and our button code:
protected void cmdUpLoad_Click(object sender, EventArgs e)
{
// save file to up-loads folder
string sFileLocal = Server.MapPath(#"~/UpLoadFiles/" + FileUpload1.FileName);
FileUpload1.SaveAs(sFileLocal);
// process csv file
TextFieldParser MyParse = new TextFieldParser(sFileLocal);
MyParse.TextFieldType = FieldType.Delimited;
MyParse.SetDelimiters(new string[] { "," });
MyParse.HasFieldsEnclosedInQuotes = true;
DataTable rstData = new DataTable();
foreach (string cCol in MyParse.ReadFields())
{
rstData.Columns.Add(cCol);
}
while (!MyParse.EndOfData)
{
string[] OneRow = MyParse.ReadFields();
rstData.Rows.Add(OneRow);
}
// example process each row of data
foreach (DataRow OneRow in rstData.Rows)
{
if (OneRow["City"].ToString() == "")
OneRow["City"] = "No City";
if (OneRow["Province"].ToString() == "")
OneRow["Province"] = "No Province";
}
// Now display results in a grid
GridView1.DataSource = rstData;
GridView1.DataBind();
}
and our output looks like this:
Please don't chew me up. As I said, I am more familiar with Java at this point and some Asp.NET as far as doing this.
I found my issue based on another example:
https://findnerd.com/list/view/How-to-read-CSV-file-in-asp-net/19762/
If you look on line 11 from the above link, they are using the following:
string path = Path.GetFullPath(filename.PostedFile.FileName);
This was it for me. I had it as
string path = Server.MapPath("~/Files/") + Path.GetFileName(filename.PostedFile.FileName);
All I know that Server.MapPath did not work but Path.GetFullPath did. My program reads the file and the saves it to a DataTable. Then I bind the data table to the datasource of the gridview and voilá, I see the data from the csv file.
I wanted to come back and put an answer in case it's pertinent to another person running with the same situation. If someone else would be kind to explain the difference between Server.MapPath and Path.GetFullPath would be nice. That would add more explanation to this topic.
Thank you all and Regards! ^_^

How do I set the path to a file I am trying to open to be opened while hosted instead of depending on localhost directories wtih ASP.net?

I'm building a website that handles 2 files (simple ones like .txt) and I'm struggling to see how I can write the path in a way that it works when eventually I host the website.
Currently, I'm using this line of code just to make it work while I am working around it:
File.ReadAllLines(#"C:\Users\pinky\source\repos\PAP\PAP\files\filename.txt");
But when I try to change it for the following bit of code:
File.ReadAllLines("/files/filename.txt");
It stops working. And the strange thing is, it only stops working for the specific page I changed the path of the files.
If I try to debug it, it gives an error 404 and asks me if I have the path of the page right (which it is). What can I do to change this?
Ok, so, in your web site, you have the root, and then some folders.
And we assume that files is one of those folders.
Lesson #1:
When a user (or you) wants to use a URL, then of course URL's are
www.mywebsite/Files/dogs.png
So, keep in mind that say in HTML markup, a src etc. Then a path name is always assumed to be from the root of your site onwards.
However, despite the above CODE BEHIND still will ALWAYS STILL use a valid windows FULL PATHNAME to the file.
So, you use a built in function called server.MapPath
MapPath will take the web based url, and convert to a full internal windows path name.
So, your code would be like this:
string strIntenalFileName = Server.MapPath("/files/data.txt");
string MyText = File.ReadAllText(strIntenalFileName);
TextBox1.Text = MyText;
So just keep in mind that say we want to set a image control to have a picture from above.
Well, then we do this:
Image1.ImageUrl = "/files/dogs.png";
But, if you need in code behind to read the file, then we have to put above expression though Server.MapPath() to translate for code behind.
So, just remember WHEN dealing with web controls, HTML markup, the of course the URL and path name is web based. But, for code behind to directly interface and use the file, then code behind needs that "plane jane" and full legal windows path name.
So, for your example, wrap the string in Server.MapPath(" your web based path goes here").
you in effect can't really know the root path name of the web hosting server, but with above, you really don't care.
Often however, one does get "messed" up. Since for the above image, I shoved in the web based url for SCR. But, if I was to read the picture and say stream the picture bytes to the web control, then I would of course first convert/get a full windows path name.
The above is not really all that confusing, but keeping this "web url", "web markup" and that of direct file use in code behind is still a VERY good concept to keep alive in your mind when dealing with files.
Now, the above is a simple tip - but one that I wish was hammered home to me.
So:
web expresions, markup = web path name from web root.
code behind:
Still always MUST be a full plane jane windows file name!
So, in your case, to get the text file, we could (and you should try this), is type in this:

C# Change File Location For Next Time Program Runs

I am relatively new to C#, however I do have some basic knowledge of code from courses in high school and university. However, there is one thing I have not been able to figure out over the years. I am currently making a Form Application for a database system that stores information in a List using Visual Studios 2010.
On my main form; when the save button is pressed, the information is then serialized into an XML file. When the information is loaded, the information is then deserialized and put into the List for use in the code. All this is working correctly.
This process of saving and loading is done based on a string which contains the file path. This string is the location of a folder on my desktop (I put it there for easy access), and I am able to change the string in the code to basically move where the information is stored.
However, I have a separate "Admin" form which is able to change this file path string. When the user clicks the button to change the file path, I get the input from a text box, check its formatting, move the current file to the new location and update the location for the save method so changes can be saved before the program is closed. From there, the program reacts the same way as if I had changed the string from inside the code.
The problem occurs when I close the program. I do not know how to tell the program when it runs again that the location has been changed from the default and look for the file in the new location. The program reacts just like the file was missing (like it should) when it looks in the default location.
So basically, how do I tell the program that the save location was changed from when it was last run so it knows to load the info from a new location?
I have tried looking for an answer since high school (about 2 years ago) and have not found a solution. As a result I usually just keep the save location as the default (which I set it to) and don't try to change it. But this time, its important that the save location can be customized. My experience with Visual Studios is limited, as everything I know is from messing around with the program and looking up stuff when needed.
If needed, I can post snippets of my code. Thank you in advance!
It seems like what you really want is to save some user-defined settings for recall at run-time. Here is a MSDN link describing some basic conventions for storing / retrieving these settings.
https://msdn.microsoft.com/en-us/library/bb397750(v=vs.110).aspx
A *.config file would suffice (depending on the scale of the application).
Otherwise, you may want to go down the route of storing these settings in a database (if the scale is rather large, or if user-authentication is required for the application).
Here is another previous question dealing with this same subject (regarding App.config files):
What is App.config in C#.NET? How to use it?
I recommend using a config file where the .exe is, and write the location there, then read it in on program startup.
In particular .net provides this class which can manage your config file for you (assuming you have an app.config in your solution, otherwise create one)
https://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.appsettings(v=vs.110).aspx

MS Word Customization can't find VSTO file

I've developed a customization in Visual Studio for Word 2010 and have the solution saved in network share (using a UNC path) and the actual Word document is saved in a folder in SharePoint.
Everything works fine, users can open the document and use the customisation and when they've gone through the steps the add-on requires they click a button which saves the completed document to a different location in SharePoint. Al good. When you however now open the newly saved document from SharePoint I get the following error message:
Cannot currently access the deployment manifest at this location:
"[URL to document path in SharePoint]". You muyst set the deployment
manifest location to a UNC share or a local path when
ClickOnceAddInDeploymentManager.RunFromFolder is true.
Have done some searches on these terms but getting nothing useful! Would appreciate any help you could offer!
Try this article:
http://msdn.microsoft.com/en-us/library/vstudio/bb772100(v=vs.110).aspx
Particularly the steps under the heading:
To put the document on a server that's running SharePoint
I don't think word trusts your document after you save it in a different location.
I figured out my problem, need to give a bit more background to explain the issue a bit better.
I'm using a number of Action Panes to create a wizard-like experience for the user. When the user hits "Next" on the first pane I have code (using ThisDocument.SaveAs2) so automatically do a Save As to a specific folder in SharePoint (actually the structure gets created on the fly before it being saved).
On the final pane when they hit Finish I was running the exact same code to Save As but to the exact same location and filename and this is what seems to have caused the problem. The bottom line is that the custom property _AssemblyLocation was changed somehow in this process to only have the filename of the vsto file without an absolute path, so on re-opening the document it was looking for this file in same location.
By simply changing this to a Save instead of a Save As it now works perfectly. Took me insane amounts of time to figure that out but my own fault!

How to use a Resource Image in Word document?

I'm working on a project that will auto-generate Word and HTML reports. If they don't provide an Image to use in the header of the Word report, the customer wants to use their logo. I have the logo stored in the resources of one of the projects as a .jpg.
The method to add a picture to a range needs the path as a string to the image, without any overloads. I know that when a file is added to the resources of the project, it doesn't exist as it gets embedded inside the .dll that gets created. Is there no way to utilize that embedded resource in that method?
Do I need to copy that file as part of the install to the directory? I'm thinking that may be the easiest solution, however what should I do for testing purposes?
I was making this a lot harder than it needed to be.
All you have to do is make an image object from the resource:
Image img = Data.Properties.Resources.ImageFile;
Then after that, all you have to do is save it:
img.Save(#"C:\DestinationFolder\Image.jpg");
Now you have the file to use however you want. It won't matter if you're in debugging or not (as far as your Application.Run location) in the event you have it in a subfolder in your project (as you should), but wouldn't necessarily have it in the same path at the end.
I was way over-thinking this the other day when I asked this question. Hopefully I'll be able to help someone else out who's having this same issue.

Categories