Excel Automation in ASP.NET - c#

I am aware that this approach is not recommended and should be avoid at all cost. So please do not answer me of using a third party library or any thing related
First the system creates a file and writes html inside it to display data. The system is fooling MS Excel by naming it with a .xls extension even though what it contains is html.
Aim:
I need to convert it to REAL XLS file. So i want to open it using COM and save it as xls.
Problem:
Now what happens is that it gives throws an exception that i don't know where it from. On the Development environment it is working pretty fine. but whenever we transfer it to the server. The problem occurs. I cannot debug on the server ( I know I must not) but i think i have no other choice. Here is the exception thrown
Server Error in '/' Application.
Exception from HRESULT: 0x800A03EC.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Runtime.InteropServices.COMException: Exception from HRESULT: 0x800A03EC.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[COMException (0x800a03ec): Exception from HRESULT: 0x800A03EC.]
PLDTGlobal.Remco.ExcelCOM.SaveFileAsXLS(String filePath, String fileName, String path)
PLDTGlobal.Remco.OtherFulfilments.BatchFiles.__InsertBDO.SaveRecord()
PLDTGlobal.Remco.OtherFulfilments.BatchFiles.__InsertBDO.cmdSave_Click(Object sender, EventArgs e)
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +57
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +18
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain() +1292
Version Information: Microsoft .NET Framework Version:1.1.4322.2032; ASP.NET Version:1.1.4322.2032.
Environment Details:
DEV
Windows XP Professional SP3,
Visual Studio 2003,
.NET 1.1,
MS EXCEL 11.0 Object Library
Server
Windows Server 2008 R2 (x64)
Here is an excerpt of the code:
public ExcelCOM()
{
try
{
excelApp = new Excel.Application();
excelApp.Visible = true;
}
catch(Exception ex)
{
ErrorLogger logger = new ErrorLogger();
logger.WriteErrorLog(ex.Message, ex.StackTrace);
throw ex;
}
}
/// <summary>
/// Opens the xml file using Excel COM library and converts it to .xls(1997-2003) format
/// </summary>
/// <param name="filePath">complete file path from target file</param>
/// <param name="fileName">filename of the target</param>
/// <param name="path">new path where to save the .xls</param>
public void SaveFileAsXLS(string filePath, string fileName, string path)
{
object missingParam = System.Reflection.Missing.Value;
string fileToCreate = path + fileName.Substring(0, fileName.Length - 4);
try
{
if(!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
excelApp.Visible = false;
Excel.Workbook workBook = excelApp.Workbooks.Open(filePath, 0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false);
Excel.Worksheet workSheet1 = (Excel.Worksheet) workBook.Sheets.get_Item(1);
workSheet1.Name = "Sheet1";
workSheet1.SaveAs(fileToCreate, Excel.XlFileFormat.xlExcel9795, missingParam, missingParam, false, missingParam, missingParam, missingParam, missingParam, missingParam);
workBook.Close(missingParam, missingParam, missingParam);
GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.ReleaseComObject(workSheet1);
Marshal.ReleaseComObject(workBook);
}
catch(Exception ex)
{
ErrorLogger logger = new ErrorLogger();
logger.WriteErrorLog(ex.Message, ex.StackTrace);
throw ex;
}
finally
{
excelApp.Quit();
Marshal.ReleaseComObject(excelApp);
}
}
I have tried giving launch permission to NETWORK SERVICE account in dcomcnfg.
Any idea about the problem and how to solve it is much appreciated.

I'm not sure this will work. I do run a development environment on my server, for just these kinds of issues. I wrote code to automate Excel in Visual Studio 2013, code works great. When I put the code into IIS 7 (2012 server), the code stops working. From my research, this is by design by Microsoft because they do not want you doing this. I had to change a whole lot of permissions to get it to even partially work. In the end, I cannot get Excel to display and officially, Microsoft says that Excel will throw errors because this is not supported.

Related

.NET Console App throws error when scheduled. Runs fine when executed manually

So I decided to make a console application to automate some repetitive jobs that I generally do on a daily basis. The objective is to move some files to a network location as backup. The application runs fine when executed manually. But when scheduled, it throws an error. On examining the log file (to which all program output is mapped), I found the following stack trace and exception message:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)
at System.IO.File.Copy(String sourceFileName, String destFileName)
at automateDump.Program.Main(String[] args) in D:\software\automateDump\Program.cs:line 78
The user name or password is incorrect.
I'm using the File.Copy(src, dest) method in System.IO.
And for context, the file paths are:
Source: D:\u01\test.file. Destination: \\NetDrive\test.file
Any help would be appreciated.
EDIT 1
Code:
if (File.Exists(movePath + et1))
{
Console.WriteLine($"Copying {et1} to network location. Size - {sizeInMegaBytes(new FileInfo(movePath + et1).Length)}");
File.Copy(movePath + et1, networkPath + et1);
Console.WriteLine("Done Copying");
}
movePath and networkPath are source and destination paths, and et1 is the file.
sizeInMegaBytes() is a utility function that I wrote. It's irrelevant in this context.
EDIT 2
Exception Handling code:
catch (Exception ex)
{
using (logger = File.AppendText(#"D:\u01\logs.txt"))
{
logger.WriteLine($"{ex.StackTrace} \n {ex.Message}");
}
}
Theory: you have not checked the option to save the user password for the task:
Note the explanatory text: using a UNC path means you are trying to access a non-local resource!

Deploying an app with Crystal Reports in IIS

I am trying to deploy an app that I used Crystal Reports in. I want to say that it works on local host as I am using IIS Express and in staging I am using IIS. This is the main difference that I can think of but just to be sure I want to write out the entire process that have done.
Build Report in Visual Studio
Create ODBC Connection on local host
Run Report in localhost - it works
publish MVC app
add ODBC connection with same name on server
copy report to correct location on IIS server
run app and report app works report doesn't.
The log that I am getting is:
FATAL 2018-08-28 03:22:30,923 37280ms Log Service GenerateReport - Exception during StringFormat: Index (zero based) must be greater than or equal to zero and less than the size of the argument list. Generate Reports at: 8/28/2018 3:22:30 AM, Exception: CrystalDecisions.CrystalReports.Engine.InternalException: Failed to open the connection.
QuoteReport 5092_4216_{0FAD9DBD-DCD7-4158-816D-56895A79B362}.rpt
Details: [Database Vendor Code: 4060 ] ---> System.Runtime.InteropServices.COMException: Failed to open the connection.
QuoteReport 5092_4216_{0FAD9DBD-DCD7-4158-816D-56895A79B362}.rpt
Details: [Database Vendor Code: 4060 ]
at CrystalDecisions.ReportAppServer.Controllers.ReportSourceClass.Export(ExportOptions pExportOptions, RequestContext pRequestContext)
at CrystalDecisions.ReportSource.EromReportSourceBase.ExportToStream(ExportRequestContext reqContext)
--- End of inner exception stack trace ---
at CrystalDecisions.ReportAppServer.ConvertDotNetToErom.ThrowDotNetException(Exception e)
at CrystalDecisions.ReportSource.EromReportSourceBase.ExportToStream(ExportRequestContext reqContext)
at CrystalDecisions.CrystalReports.Engine.FormatEngine.ExportToStream(ExportRequestContext reqContext)
at CrystalDecisions.CrystalReports.Engine.ReportDocument.ExportToStream(ExportOptions options)
at CrystalDecisions.CrystalReports.Engine.ReportDocument.ExportToStream(ExportFormatType formatType)
at QuickQuote.Controllers.ReportsController.GenerateReport(Int32 reportId, String json) in C:\Users\James\Source\Repos\QuickQuote3\QuickQuote\Controllers\ReportsController.cs:line 84{}
Can someone please tell me what my issue is? I have google this error and I don't understand what my issue is.
try
{
var stream = _reportBuilder.BuildReport(dataSet, report, filePath, parameters);
stream.Seek(0, SeekOrigin.Begin);
return File(stream, "application/pdf", $"Quote{report.Name}-{DateTime.Now}.pdf");
}
catch (Exception e)
{
_loggingService.FatalFormat($"Generate Reports at: {DateTime.Now}, Exception: {e}");
throw;
}
Inside reportBuilder.BuildReport is where it is breaking. I'm sure that it is this line:
var stream = reportDocument.ExportToStream(ExportFormatType.PortableDocFormat);
BuildReport method:
public Stream BuildReport(DataSet dataSet, Report report, string path, string parameters)
{
var reportDocument = new ReportDocument();
reportDocument.Load(path);
reportDocument.SetDataSource(dataSet);
AddParametersToReport(ref reportDocument, report, parameters);
return reportDocument.ExportToStream(ExportFormatType.PortableDocFormat);
}
The exception message is Failed to open the connection.
Verify if System Data Sources are set up correctly in ODBC Data Source Administrator (for both 32-bit and 64-bit).
You may get Database logon failed error, as credentials specified in .rpt file might be invalid for the database. The solution is to provide database credentials in code:
public Stream BuildReport(DataSet dataSet, Report report, string path, string parameters)
{
try
{
var reportDocument = new ReportDocument();
reportDocument.Load(path);
reportDocument.SetDataSource(dataSet);
AddParametersToReport(ref reportDocument, report, parameters);
// Set database credentials
reportDocument.SetDatabaseLogon("dbUsername", "dbPassword");
return ReportDocument.ExportToStream(ExportFormatType.PortableDocFormat);
}
catch(Exception ex)
{
_loggingService.FatalFormat($"Exception: {ex}");
throw;
}
}

screen scraping from TN3270 using Microsoft Host Integration Server 2013 / 2016 and ASP.Net

We are trying to develop a new web application for screen scraping from TN3270. We are using visual studio 2015 and HIS 2016.
Following code is written to connect TN3270
var display = new SessionDisplay();
var connection = new SessionConnectionDisplay();
connection.DeviceType = TNDeviceType.IBM3278Model2;
connection.Transport = SessionDisplayTransport.TN3270;
connection.TN3270Port = 23;
connection.TN3270Server = "server name";
connection.HostCodePage = 37;
display.Connect(connection);
The code is working fine when we execute it from console or windows application. But when we try to call from web application, I'm getting the following error:
An exception of type 'System.Runtime.InteropServices.COMException' occurred in Microsoft.HostIntegration.SNA.Session.dll but was not handled in user code
Additional information: Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))
StackTrace
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32
errorCode, IntPtr errorInfo)
at Microsoft.HostIntegration.SNA.Session.SessionConnectionDisplay.CreateSessionConnection()
at
Microsoft.HostIntegration.SNA.Session.SessionConnectionDisplay.ConnectToSessionDisplay(SessionDisplay
connectedSession)
at Microsoft.HostIntegration.SNA.Session.SessionDisplay.Connect(SessionConnectionDisplay
connection)
I would appreciate any help on this.
connection.Implementation = ImplementationDetail.ManagedTn;
setting this property solved my problem.

SaveFileDialog.ShowDialog() thrown FileNotFound exception

The following code works fine on Windows 7 (32-bit), but when ported to 64-bit, I get an exception stating "File Not Found". I have built the project in 64-bit configuration but the issue still persists.
The issue occurs if the machine does not have Office installed.
The code is as follows:
try
{
SaveFileDialog fileDialog = new SaveFileDialog();
fileDialog.InitialDirectory = path;
// set the default extension as mdb.
fileDialog.DefaultExt = ".mdb";
// allow the user to select the file type as CSV, XML or MDB.
fileDialog.Filter = "CSV (*.csv)|*.csv|XML (*.xml)|*.xml|MDB (*.mdb)|*.mdb";
fileDialog.RestoreDirectory = true;
if (DialogResult.OK == fileDialog.ShowDialog()) // exception occured
{
this.fileNameTextBox.Text = fileDialog.FileName;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
The question here is what's the value of "path". x86 and x64 machines may have different folder configurations, e.g. Program Files (x86) is one of them. You may start with Environment.SpecialFolders enum, those paths should be valid.

Downloading file from server for user logged in as guest

I have a code which allows you to download any file from server to your local host.
This code works fine when i log in as administrator but when i log in as guest user it does not let me download.. and i get an error message saying..
External component has thrown an exception.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Runtime.InteropServices.SEHException: External component has thrown an exception.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
My code is as follows
string filepath = restoredFilename.ToString();
// Create New instance of FileInfo class to get the properties of the file being downloaded
FileInfo myfile = new FileInfo(filepath);
// Checking if file exists
if (myfile.Exists)
{
// Clear the content of the response
Response.ClearContent();
// Add the file name and attachment, which will force the open/cancel/save dialog box to show, to the header
Response.AddHeader("Content-Disposition", "attachment; filename=" + myfile.Name);
//Response.AddHeader("Content-Disposition", "inline; filename=" + myfile.Name);
// Add the file size into the response header
Response.AddHeader("Content-Length", myfile.Length.ToString());
// Set the ContentType
Response.ContentType = ReturnExtension(myfile.Extension.ToLower());
//// Write the file into the response (TransmitFile is for ASP.NET 2.0. In ASP.NET 1.1 you have to use WriteFile instead)
Response.TransmitFile(myfile.FullName);
// End the response
Response.End();
}
I have to download the file using guest.. please help thanks
Stack Trace:
[SEHException (0x80004005): External component has thrown an exception.]
xyzgui.Guest.DriveContents.RestoreOneFileForGUI(Int32 machineID_Download, Int64 fileID, StringBuilder restoredFilename, UInt32 restoredFilenameBufsize) +0
xyzgui.Guest.DriveContents.file_Click(Object sender, EventArgs e) in C:\Users\jagmit\Documents\Visual Studio 2008\Projects\xyzgui\xyzgui\Guest\DriveContents.aspx.cs:341
System.Web.UI.WebControls.LinkButton.OnClick(EventArgs e) +111
System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +79
System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +175
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1565
What authentication mechanism are you using: Forms, or Windows?
Do you have impersonation turned on?
I believe that the error you are seeing is generally thrown when there's a security issue - which sounds likely when you say "when I log in as administrator".
Is there more to the method RestoreOneFileForGUI that we're not seeing - because it looks like something is throwing a security exception outside of .NET - if it was as simple as the guest account (the account the website is running under) not having access to the file path then you'd see a standard SecurityException or UnauthorizedException from the FileInfo constructor.

Categories

Resources