Can I modify a Word '97 document in C# - c#

Have read a few variants of this, but nothing exactly addresses the problem I have.
I'm part of a data migration team, and one of our tasks is migrating existing documents from one environment to another, and once migrated, maintain any existing hyperlinks within.
For relatively new documents (Office 2007+), this is no problem. I've had a look at DocX by Cathal Coffey; NPOI which apparently is unstable and not recommended for use - or at least the part I need anyway; GemBox and others, and while they work perfectly for newer documents, none of them can deal with opening/modifying documents from Word '97. Thankfully documents created under Win 3.1 or Word for Windows 2 are out of scope.
I realise that these documents are very old and not supported any more and as such, may pose security risks, I also realise that they should have been maintained and brought up to date by their respective teams but for whatever reason, they haven't been and now it's my job to try and come up with a way to do this.
Using the oldest version of the COM object I have available (Microsoft Office 14.0 Object Library, Version 8.5.0.0) I run into problems with making changes to Trust Settings, Registry changes etc. Doing all of this leads to its own problems such as having to open the document in protected mode when I need to make changes to it, and besides, when this gets deployed, I won't have access to the Trust Center nor to the Registry. Examining the document in memory shows the Hyperlink collection but won't let me see the details like I can in DocX for example.
Is there way to do this or am I going back saying these docs are too old, unsupported and the relevant teams need to do a better job of maintaining their documents? Thought about maybe trying to read the doc in as HTML then examining any href tags, thoughts? Can I get my hands on older versions of the Microsft DLLs, and even if I can, will they be compatible with VS 2015? 3rd party libraries are an option (Gem, DocX etc.) but something like Aspose Documents is out of the question as the license is $1000.
Nice to have - something that will work without needing Office installed would be truly the stuff of dreams.
Thanks everyone.

The simplest and fastest way would be to convert the documents to Open XML format. This can be easily done on the command line (replace the path with the path where winword.exe is installed on your machine):
"C:\Program Files\Microsoft Office\Office15\wordconv.exe" -oice -nme <input file> <output file>
where and need to be fully qualified path names.
The command can be easily applied to multiple documents using for:
for %F in (*.doc) do "C:\Program Files\Microsoft Office\Office12\wordconv.exe" -oice -nme "%F" "%Fx"
Once the files are converted you can modify the documents by editing the raw XML inside the zip package or by using Microsoft's Open XML SDK.

Related

Determine SVN working copy revision from C#

I'm writing a small console tool in C# that needs to know the revision number of an SVN working copy directory to process other data with this number. I already have support for SVN 1.4 to 1.6 by directly reading the entries file in all .svn directories. But SVN 1.7 has changed that to use a single .svn directory with an SQLite database in it.
What's the best method to determine the revision number of a working directory?
I've just tried to use SharpSVN, but it's largely undocumented and I can't figure out how to use it. It's also very huge with 5 MB and potentially several DLLs.
I can't find a simple SVN command line client that is freely downloadable. Also, last time I've seen one, it was huge and consisted of numerous files which is not exactly portable. (It would be great if my tool would only come as a single .exe file.)
Another option would be to use an SQLite library (available as a single separate DLL) and dig into the database myself. I've already done basic research on this but I'm not sure how to detect uncommitted modifications.
TortoiseSVN, which is likely already installed on the machines that will be using my tool, can't be used because it contains everything in a single GUI application, no DLLs that I could reuse.
If you don't want SharpSVN and work with Working Copy, then in 99% host may have SVN CLI-tools.
Check callability of svnversion and call it svnversion <PATH-TO-WC>, intercept output
I use Tortoise SVN's command line tool called 'SubWCRev' for this purpose (http://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-subwcrev.html). It allows to determine latest revisions, commit date and more... The drawback of this solution is that this tool work with files, so you will need to define template file and parse tool's output file. This works good for me though.

Is there an Adobe equivalent to the Java deployment.properties file?

Just as the title states, is there an Adobe equivalent to the Java deployment.properties file?
I am writing a c# application to test installations of application in our network. The top three on my boss's list are java, flash, and reader. I need to be able to find out what versions of each application are installed on a machine for the reports im going to generate (force the user to update/etc).
I know i can check version number and confirm the ability of IE to access my JRE by checking "\Sun\Java\Deployment\deployment.properties". What file would I check to confirm the same for adobe reader and flash?
Thanks in advance for any help given or links provided to more info.
edit: I need to do this from the browser.
This is not a very clean solution, but since the only "official" way seems to be to check it from the Windows registries perhaps this will help:
We know that the flash files are located are in the (windows directory)\system32\Macromed\Flash (or SysWow64\Macromed\Flash on 64 bit systems).
Each time a flash updates it keeps the track of the progress in the log files. Depending on the flash version you will either have a) install.log (very old versions of flash) or b) FlashInstall.log
a) If you browse through the file you see various entires and one type goes like this:WriteRegStr: "HKEY_CURRENT_USER\SOFTWARE\Macromedia\FlashPlayer" "FlashPlayerVersion"="10.0.45.2".
Now you can just go through that file bottom-top and match the "FlashPlayerVersion"= string to get the most recent version.
However, this is for a really old versions of flash and the install.log file never got deleted from this directory, so make sure you check for the FlashInstall.log too!
b) Use a similar approach, except the new install logs don't keep the "WriteRegStr" information. Now you can instead look for the dll file name itself, for example my last update created an install log 0009 [I] 00000014 C:\WINDOWS\system32\Macromed\Flash\NPSWF32_11_5_502_146.dll, meaning my flash version is 11.5.502.146
another options are to
check the plugin core files creation date and compare with the versions release dates (quite unreliable in case someone somehow manages to install an older version)
check the actual property of the NPSWF[..version..].dll file. You can see all the complete and precise version details in the "Version" tab. however, I don't know how to access the rightclick->properties from inside a script, so you'll have to find out by yourself if you decide to go for this option
ask the unicorns

End user wants to add languages dynamically to his website

We have to build an event registration website for our client in ASP.NET using C#.
One of the requirements is that the client wants to add new foreign languages to his website himself using en excel file. I know how to make a website multilingual in Visual Studio, but I have no idea how to generate a resource file based on an excel file in code.
I also noticed VS generates a second file called Resource.en.designer.cs but I can't find any documentation how to generate that file either.
btw, the enduser is anything but IT-related. He knows his way around excel though (obviously).
Any help is appreciated!
Yoeri
EDIT:
!Robert Levy Provided a good method!
HOW TO:
STEP 1:
Read the excel file (using an OleDBAdapter was the best method for me, as you can use column headers etc)
Write the language to a txt file in this format:
KEY=TRANSLATION
no spaces or anything else
STEP 2:
Locate ResGen.exe on your computer (it comes with Visual Studio, so look somewhere like c:\program files\visual studio\sdk... however I found it # C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\ResGen.exe)
STEP 3:
Invoke the exe with Process.Start("resgen.exe")
hint: use ProcesStartInfo for easy argument and preferences settings
(STEP 4:)
Move the file to your desired location (I find the App_GlobalResources works perfectly)
STEP 5:
Set the user currentUIculture to your desired culture!
ResGen.exe will compile resource files for you. You could either get him to deliver text files in the format used by that tool or write your own code that extracts from excel to generate the text files. Then just invoke this EXE and deploy your newly generated resource DLL. I am assuming you already know how to read things from resource files and use the appropriate one based on user preference.
http://msdn.microsoft.com/en-us/library/ccec7sz1.aspx
This is probably one place where you would like to use resources from database rather than simple resx files. It would be easier just to populate database table(s) with Excel data than transforming it to standard resx file (it could be a problem in the future if MS decided to modify file format).
So I would suggest you to write your own ResourceReader which would load strings from database (it could load it directly from Excel as well, but for many reasons I wouldn't recommend this method).
You should ask your end-user if they really have to get another language 'on the fly' and how many languages they expect they are going to add.
Otherwise, e-mailing the Excel file to you and manually creating the resource file might be by far the cheapest solution....

Can I determine the temporary path of an open excel workbook?

I'm trying to create an excel file from ASP.NET. I assume this file is created somewhere temporary right? How can I get this location?
What are you using to create the Excel file? Since you have an ASP.NET tag I hope you are not trying to do this with Office COM Automation, it is not supported and trust me it is very very unreliable. See this link from Microsoft http://support.microsoft.com/kb/257757
Key message from the link
Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.
I would suggest that you take a look at using NPOI library, it is very fast and works reliably on the server side. And you can then control where the file is generated.
If you are using a temp path or a temp file you should not care about where it is. If you need to care you should use a concrete path with a concrete file. You can also use a MemoryStream to do this all without HardDisk.
EDIT:
Additional to the comment I recommend you to use Open XML to create a Excel Sheet. If this is an option let me know than will I post more on that.
I must say I didn't know this article from Chris Taylors post and if I had found this one last year it had saved me a lot of time. But what I must say at this point; it is possible to get a serverside solution running which uses interop and I need it last year. But it was a pain till it work and if anyone want to give it a try here are some advices:
you should not use interop directly
from a ASP apllication
you can't use impersonation (it may
fail unexpected)
you will need a service which runs as
System
you need a executable that runs the
interop
you have to manage the the execution
through the service (and I mean
manage, not just starting)
And again; I don't recommend to do this. Use any other solution if you. (MS Supports automation services with SharePoint2010)

Why do custom file properties, set using the DSOFile library, not persist after saving?

I am currently working on a plugin for AutoCAD that allows users to interact with a document versioning application, and in order to sync files between the remote repository and local machine, I had planned on using custom file properties. The properties would be set when a file is initially downloaded, and then persisted for as long as the file remains on the user's local drive. I am not really interested in an AutoCAD-specific solution, because my plugin will deal with files other than AutoCAD drawings (text files, image files, among others). Therefore, I want a library that can handle as many potential file types as possible.
When searching for how to implement this kind of thing in C#, I almost immediately came across the DSOFile library. Everything I read said it was designed for MS Office, but that it should work with any file, as long as the file system is NTFS (at least that's my understanding). I had no problem setting custom properties on files such as plain-text documents (.txt), AutoCAD drawings (.dwg), and images (.jpg, .tif, etc). However, I noticed that once any of these files were saved, the custom properties were wiped out. The only case in which I saw custom properties were persisted after saving, were on MS Office documents. I figured this issue was related to the application that I was using to save the files (AutoCAD, MS Paint, notepad, etc), but I can't be 100% sure of that. Before I decide to go with a solution other than using DSOFile, I wanted to see if anyone on SO had some insight in to this issue.
I tested using my own code and using the demo that comes with DSOFile, and saw the same result both times. Custom properties were wiped out after saving any type of file other than an MS Office (Word and Excel) document.
Here is an example similar to the code I would use to add a new custom property...
var docProperties = new OleDocumentProperties();
docProperties.Open("myfile.txt", false, dsoFileOpenOptions.dsoOptionDefault);
try
{
object value = "some value";
docProperties.CustomProperties.Add("MyCustomProp", ref value);
}
finally
{
docProperties.Close(true); // save and close
}
This may be too late but I've used this a bit or Autodesk Revit RFA files as well as PDF files and it works fine. You can't edit them while the RFA is open though.
Did you call docProperties.Save() at all?

Categories

Resources