using System; using System.Collections.Generic; using System.IO; using unoidl.com.sun.star.beans; using unoidl.com.sun.star.frame; using unoidl.com.sun.star.lang; using unoidl.com.sun.star.uno; namespace RobvanderWoude { internal class FixWordUnreadableContent { static readonly string progver = "1.00"; static int Main( string[] args ) { string fileIn, fileOut; #region Command Line Arguments if ( args.Length != 1 || args[0] == "/?" ) { return ShowHelp( ); } fileIn = Path.GetFullPath( args[0] ); /* if ( !Path.GetExtension( fileIn ).Equals( ".odt", StringComparison.OrdinalIgnoreCase ) ) { return ShowHelp( "Invalid input file type/extension" ); } */ if ( !File.Exists( fileIn ) ) { return ShowHelp( "Input file does not exist" ); } if ( !Directory.GetParent( fileIn ).Exists ) { return ShowHelp( "Parent folder of input file does not exist" ); } fileOut = Path.Combine( Path.GetDirectoryName( fileIn ), Path.GetFileNameWithoutExtension( fileIn ) + ".repaired.docx" ); #endregion Command Line Arguments #region Requirements if ( typeof( XComponentContext ) == null ) { return ShowHelp( "OpenOffice/LibreOffice SDK was not found." ); } #endregion Requirements bool success = SaveRepairedDocx( fileIn, fileOut ); if ( !success ) { return ShowHelp( "Could not repair and save the file" ); } return 0; } static bool SaveRepairedDocx( string fileIn, string fileOut ) { try { // The main functionality uses OpenOffice's UNO components // http://en.wikipedia.org/wiki/Universal_Network_Objects string urlIn = "file:///" + Path.GetFullPath( fileIn ).Replace( "\\", "/" ); string urlOut = "file:///" + Path.GetFullPath( fileOut ).Replace( "\\", "/" ); XComponentContext unoBootstrap = uno.util.Bootstrap.bootstrap( ); XMultiServiceFactory unoServiceMan = (XMultiServiceFactory)unoBootstrap.getServiceManager( ); XComponentLoader unoDesk = (XComponentLoader)unoServiceMan.createInstance( "com.sun.star.frame.Desktop" ); PropertyValue[] inputProperties = new PropertyValue[1]; inputProperties[0] = new PropertyValue( ); inputProperties[0].Name = "Hidden"; inputProperties[0].Value = new uno.Any( true ); XComponent unoDoc = unoDesk.loadComponentFromURL( urlIn, "_blank", 0, inputProperties ); PropertyValue[] outputProperties = new PropertyValue[1]; outputProperties[0] = new PropertyValue( ); outputProperties[0].Name = "FilterName"; outputProperties[0].Value = new uno.Any( "MS Word 2007 XML" ); ( (XStorable)unoDoc ).storeToURL( urlOut, outputProperties ); ( (XComponent)unoDoc ).dispose( ); unoDoc = null; return true; } catch ( unoidl.com.sun.star.uno.Exception ) { return false; } } #region Error Handling public static int ShowHelp( params string[] errmsg ) { #region Error Message if ( errmsg.Length > 0 ) { List errargs = new List( errmsg ); errargs.RemoveAt( 0 ); Console.Error.WriteLine( ); Console.ForegroundColor = ConsoleColor.Red; Console.Error.Write( "ERROR:\t" ); Console.ForegroundColor = ConsoleColor.White; Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) ); Console.ResetColor( ); } #endregion Error Message #region Help Text /* FixWordUnreadableContent.exe, Version 1.00 Use LibreOffice/OpenOffice to fix Word documents with unreadable content Usage: FixWordUnreadableContent.exe inputfile Where: inputfile is the Word file to be repaired Notes: If the program successfully repaired the Word document with unreadable content, it saves it with the same name and location, replacing the .docx extension by .repaired.docx The repaired document will miss the corrupted parts, but will at least be editable without "unreadable content" error message. Requires LibreOffice or OpenOffice, its SDK and a Java runtime. Tested with LibreOffice 24.8.0.3 and Java 22.0.1+8-16. Return code ("Errorlevel") 1 in case of errors, otherwise 0. Written by Rob van der Woude https://www.robvanderwoude.com */ #endregion Help Text #region Display Help Text Console.Error.WriteLine( ); Console.Error.WriteLine( "FixWordUnreadableContent.exe, Version {0}", progver ); Console.Error.WriteLine( "Use LibreOffice/OpenOffice to fix Word documents with unreadable content" ); Console.Error.WriteLine( ); Console.Error.Write( "Usage: " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.WriteLine( "FixWordUnreadableContent.exe inputfile" ); Console.ResetColor( ); Console.Error.WriteLine( ); Console.Error.Write( "Where: " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( "inputfile" ); Console.ResetColor( ); Console.Error.WriteLine( " is the Word file to be repaired" ); Console.Error.WriteLine( ); Console.Error.WriteLine( "Notes: If the program successfully repaired the Word document with" ); Console.Error.WriteLine( " unreadable content, it saves it with the same name and location," ); Console.Error.WriteLine( " replacing the .docx extension by .repaired.docx" ); Console.Error.WriteLine( " The repaired document will miss the corrupted parts, but will at" ); Console.Error.WriteLine( " least be editable without \"unreadable content\" error message." ); Console.Error.WriteLine( " Requires LibreOffice or OpenOffice, its SDK and a Java runtime." ); Console.Error.WriteLine( " Tested with LibreOffice 24.8.0.3 and Java 22.0.1+8-16." ); Console.Error.WriteLine( " Return code (\"Errorlevel\") 1 in case of errors, otherwise 0." ); Console.Error.WriteLine( ); Console.Error.WriteLine( "Written by Rob van der Woude" ); Console.Error.WriteLine( "https://www.robvanderwoude.com" ); #endregion Display Help Text return 1; } #endregion Error Handling } }