deleting an excel file in C#, Taskmanager process is not stopped - excel

I am working on a wpf application.
I am copying the data to excel sheet from database and saving the file and closing it once the operation is completed.
My question is:
How to stop the Process(EXCEL.EXE) in TaskManager->Processes ?
I have to delete the file after the operation is completed. I have written a pieceof code to stop the process in taskmanager, but didnt work..
private void EndExcelAPP(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
}
catch
{
}
finally
{
obj = null;
}
}
I cant delete it since using this too.. since it says the process is used by another process.
Please help me how to stop this process programatically in c# and delete the fiile ?
Thanks
Ramm

You have to make sure you close the workbook and exit the application:
Excel.Application xlApp ;
Excel.Workbook xlWorkBook ;
/* do your stuff */
xlWorkbook.Close();
xlApp.Exit();
Marshal.ReleaseComObject(xlWorkBook);
Marshal.ReleaseComObject(xlApp);

Sounds like you're not cleaning up after yourself (or more accurately, after Excel). Check out:
How to properly clean up Excel interop objects in C#
After Excel has stopped running in the background you should be able to delete the file. And you shouldn't have to write code to kill the process.

Did you close the workbook before releasing it? That's what I do and it works for me. Here's an example.

Related

Excel VSTO Addin Using ChromiumFX Issue

I'm trying to invoke browser control in a Window Form using ChromiumFX framework in the Excel VSTO Addin.
The excel application throws the following alerts and another excel instance gets started.
Sorry, we couldn't find Files\Microsoft.xlsx. Is is possible it was removed, renamed of deleted ?
Sorry, we couldn't find Office\root\Office16\debug.log. Is is possible it was removed, renamed of deleted ?
Although I’m able to load the URL in the Web Browser control but i get the above errors multiple time and every time another instance of excel gets initiated.
I’m invoking the following piece of code after which the alerts start appearing.
var assemblyDir = System.IO.Path.GetDirectoryName(new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath);
Environment.CurrentDirectory = System.IO.Path.Combine(assemblyDir, #".");
if (CfxRuntime.PlatformArch == CfxPlatformArch.x64)
CfxRuntime.LibCefDirPath = #"cef\Release64";
else
CfxRuntime.LibCefDirPath = #"cef\Release";
Chromium.WebBrowser.ChromiumWebBrowser.OnBeforeCfxInitialize += ChromiumWebBrowser_OnBeforeCfxInitialize;
ChromiumWebBrowser.OnBeforeCommandLineProcessing += ChromiumWebBrowser_OnBeforeCommandLineProcessing;
Chromium.WebBrowser.ChromiumWebBrowser.Initialize();
Any suggestions on what i might be doing wrong ? Or what piece of code i’m missing ?

Excel JS API - SettingCollection not persisting

I'm trying to update my Excel add-in to use the workbook SettingCollection instead of the Office.context.document.settings object. The documentation seems to suggest they are functionally equivalent, but with document.settings I can call saveAsync() and see my data persisted (in the PropertyBag in a webextensions.xml).
With ctx.workbook.settings.add('key', 'value'), I can get the settings and get them in the current session, but they don't get added to the webextensions.xml and aren't available on the next open of the add-in.
Is there a version of saveAsync for workbook settings that I'm missing? I assumed context.sync would take care of it, but I haven't had any luck.
Edit: I figured out what was causing my initial issue, but the problem is still there. When I close the browser tab with Excel Online and re-open it with my add-in, the settings are not persisting. Nothing is getting added to webextensions.xml.
Here is an example Excel.run()
window.Excel.run(async ctx => {
ctx.workbook.settings.add('hello', 'world');
await ctx.sync();
let setting = ctx.workbook.settings.getItemOrNullObject('hello');
setting.load('value');
await ctx.sync();
console.log(setting.value);
});
The setting 'hello' sets and exists the next if I relaunch my add-in, but not if I close the file and open my add-in.
there is a bug with the Excel rich API for settings, can you please try the Shared API flavor as a workaround in the meantime...
function createSetting() {
Office.context.document.settings.set("Foo", "bar");
Office.context.document.settings.saveAsync();
}
function readSetting() {
console.log(Office.context.document.settings.get("Foo"));
}

EXCEL.EXE Running even after i use excelObj.Quit(); in activexscripts

Since, I could not find any satifying answer on the web for this question, I put forth it in Stackoverflow. I use activexscript to manipulate Excel, Outlook. But, even after I runexcelobj.Quit() at the end, I see an EXCEL.EXE still running in the task manager.
I tried using excelobj.Application.Quit() (as mentioned by some post in stackoverflow)also did not resolve the problem.
Can somebody help me with this??
Here's one way the application goes away in JScript:
// WScript.CreateObject for cscript.exe or wscript.exe
var excel = new ActiveXObject("Excel.Application");
// ...
excel.Quit();
// null out EVERY reference to Excel objects
excel = null;
CollectGarbage();

setCacheDuration on Wicket DownloadLink

I am currently using a downloadLink in Wicket to allow a user to download a created excel file, and then to be deleted afterwards. When this is done over SSL IE gives me an error:
"Unable to download.
Internet Explorer was unable to open this site. The requested site is either unavailable or cannot be found. Please try again later. "
here:
http://support.microsoft.com/kb/323308
after doing some reading from the above microsoft support link, it seems it is because
because it's over SSL, and I have
response.setHeader("Cache-Control", "no-cache, max-age=0, must-revalidate, no-store");
I set my downloadLink like so:
private void setupDownloadLink()
{
IModel excelFileModel = new AbstractReadOnlyModel()
{
public Object getObject()
{
return excelCreator();
}
};
auditDownloadlink = new DownloadLink("auditDownloadlink", excelFileModel);
auditDownloadlink.setOutputMarkupPlaceholderTag(true);
auditDownloadlink.setDeleteAfterDownload(true);
auditDownloadlink.setCacheDuration(Duration.NONE);
auditDownloadlink.setVisible(false);
findUserForm.add(auditDownloadlink);
}
However, it seems to work if I do: auditDownloadlink.setCacheDuration(Duration.Minute);
I guess I am confused on what is happening with this. Does the setCacheDuration mean how long after the file is created, it will be available for before it is deleted? Or does this mean how long in total the file will be available for from the start of declaring it?
inside the excelCreator() method I call File excelfile = new File("Access.xls"); and then go ahead and process all of the excel work and create the spreadsheet, then at the end of the method I call:
FileOutputStream output = new FileOutputStream(excelfile);
workbook.write(output);
output.close();
Will the duration time I set start from the moment I call File excelfile = new File("ssaUserIDAccess.xls")?
What is the best duration and setup I should use for this scenario? Because the files can get quit huge, and can take some time to create if it is big enough.
Thanks!
I do not remember the reason, but we had the same problem on SSL/IE and we just set the cache duration to 1 second that is enough. Just it cannot be NONE. Another solution we've never found.
auditDownloadlink.setCacheDuration(Duration.ONE_SECOND)

SharePoint ItemAdded and SPFile.OpenBinary(), zero bytes

I have an event receiver tied to a SharePoint 2010 picture library. When a picture is uploaded, I want to open it for processing. Files uploaded with the web interface work fine, but files copied via Windows Explorer view return zero bytes. Simplified code below.
public override void ItemAdded(SPItemEventProperties properties)
{
SPListItem item = properties.ListItem;
SPFile file = item.File;
byte[] buffer = file.OpenBinary(); //buffer has zero bytes for files copied in Windows Explorer!
}
If I insert a delay before opening, it works.
public override void ItemAdded(SPItemEventProperties properties)
{
SPListItem item = properties.ListItem;
SPFile file = item.File;
System.Threading.Thread.Sleep(2000);
byte[] buffer = file.OpenBinary(); //buffer now populated correctly
}
But I though that ItemAdded was only called after everything was done, including file upload.
I also found that file.CanOpenFile(true) always returns true, whether or not OpenBinary works.
How can I make sure the file is ready to open before I call OpenBinary()?
I don't like the Thread.Sleep solution, because I'm sure larger files or a busier server would require more wait. The time required can't be predicted, and I don't want to loop and try again forever.
Update: I originally thought the failure to open was caused by larger files. Question has been updated to reflect the explorer view as the cause. I also find that Windows Explorer copy also triggers ItemUpdated (twice), and I am able to open the file here. A little messy to have 3 triggers, 2 calls to do 1 thing, so I am still open to suggestions.
I just encountered this issue today on SharePoint 2013. I've taken the suggestions listed here and improved upon them.
It's fine making the thread sleep for 2 seconds, but what happens when you have a large file? You're going to run into the same issue.
My code fix is as follows:
//Check if the SPContext is null since Explorer View isn't within the context
if (SPContext.Current == null)
{
//If the initial file length is 0, pause the thread for 2 seconds
if (properties.ListItem.File.Length == 0)
{
System.Threading.Thread.Sleep(2000);
//Since our item exists, run the GetItemById to instantiate a new and updated SPListItem object
var spFile = properties.List.GetItemById(properties.ListItemId);
//SharePoint places an Exclusive lock on the file while the data is being loaded into the file
while (spFile.File.LockType != SPFile.SPLockType.None)
{
System.Threading.Thread.Sleep(2000);
spFile = properties.List.GetItemById(properties.ListItemId);
//We need to check if the file exists, otherwise it will loop forever if someone decides to cancel the upload
if (!spFile.File.Exists)
return;
}
//If someone thought it was a good idea to actually load a 0 byte file, don't do anything else
if (spFile.File.Length == 0)
return;
}
}
I face the same Problem within SP2010 and SP2013. Any Idea how to solve this?
Somehow this have something to do with bigger files. Small Files work without any problems, bigger files (400kb) won't work always.
I have only one hint. If you copy & paste a file over windows explorer (WebDAV) to the Library the EventHandle (ItemAdded) will trigger as soon the File was created. But this doesn't mean the File is already filled with data. I saw this once, my debugger hit my breakpoint even while windows was still busy with the copyprocess.
Would be great to know when the copyprocess is finished. I thought i could do this by just do "spfile.openBinary()" and if its empty, just wait 2 sec and do it again until it will get something bigger than 0 bytes. But this doesnt work! It only work if you are waiting BEFORE you call openBinary() the first time, all other times of calling openBinary() lead to the same result.

Resources