(从帖子中得到一些后续内容(仍然没有答案):https://stackoverflow.com/q/6197829/314661)
使用以下代码
Application app = new Application();
_Document doc = app.Documents.Open("myDocPath.docx", false, false, false);
doc.PrintOut(false);
doc.Close();
Run Code Online (Sandbox Code Playgroud)
我试图以编程方式打开并打印文件.
问题是每次运行上面的代码时都会启动一个新的WINWORD.exe进程,很明显这会很快占用所有内存.
应用程序类似乎不包含dispose/close或类似方法.
经过一番研究后我(实现了)并将代码更改为以下内容.
Application app = new Application();
_Document doc = app.Documents.Open(fullFilePath + ".doc", false, false, false);
doc.PrintOut(false);
doc.Close();
int res = System.Runtime.InteropServices.Marshal.ReleaseComObject(doc);
int res1 = System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
Run Code Online (Sandbox Code Playgroud)
我可以看到剩余的引用计数为零,但过程仍然存在?
PS:我正在使用Microsoft.Office.Interop库的第14版.
我使用office interop将DataTable导出到Excel文件.问题是,Excel不会识别日期,而是显示数字.在另一种情况下,我传递一个字符串,然后将其识别为日期.在这两种情况下,数据都搞砸了.
我尝试过NumberFormat @,它应该以文本格式存储单元格,但它也不起作用.
Application app = new Application();
app.Visible = false;
app.ScreenUpdating = false;
app.DisplayAlerts = false;
app.EnableAnimations = false;
app.EnableAutoComplete = false;
app.EnableSound = false;
app.EnableTipWizard = false;
app.ErrorCheckingOptions.BackgroundChecking = false;
Workbook wb = app.Workbooks.Add(XlWBATemplate.xlWBATWorksheet);
Worksheet ws = (Worksheet)wb.Worksheets[1];
for (int j = 0; j < dt.Rows.Count; j++)
{
for (int i = 0; i < dt.Columns.Count; i++)
{
Range rng = ws.Cells[j+2, i+1]as Range;
rng.Value2 = dt.Rows[j][i].ToString();
rng.NumberFormat = "@";
}
}
wb.SaveAs(filename, Missing.Value, Missing.Value, Missing.Value, Missing.Value, …Run Code Online (Sandbox Code Playgroud) 我正在寻找一种在Outlook窗口中打开新邮件的方法.
我需要以编程方式填写:from,to,subject,body information,但是保持这个新的邮件窗口打开,这样用户就可以验证内容/添加内容然后像普通的Outlook邮件一样发送.
发现:
Process.Start(String.Format(
"mailto:{0}?subject={1}&cc={2}&bcc={3}&body={4}",
address, subject, cc, bcc, body))
Run Code Online (Sandbox Code Playgroud)
但是没有"发件人"选项(我的用户有多个邮箱...)
有什么建议吗?
编辑
另请参阅如何正确清理Excel互操作对象?.我最近遇到了这个问题,它提供了很多关于如何正确处理COM对象的问题的见解.绝对检查超出第一个(标记的)答案,因为其他答案超出了简单的"不要使用两个点"和" ReleaseComObject用于每个com对象"的建议.
我首先重新审视了这个问题,因为我意识到尽管注册和处理所有COM对象非常彻底,但我的Excel实例仍然没有得到妥善处理.事实证明,有些方法可以创建完全不明显的COM对象(即,即使您从不使用两个点,也可以错过COM对象).此外,即使您是彻底的,如果您的项目增长超过一定的大小,错过COM对象的机会接近100%.当发生这种情况时,很难找到你错过的那个.上面链接的问题的答案提供了一些其他技术,以确保Excel实例肯定关闭.同时,我对我ComObjectManager(下面)做了一个小的(但重要的)更新,以反映我从上面链接的问题中学到的东西.
原始问题
我已经看到了几个Marshal.ReleaseComObject()与Excel Interop对象一起使用的例子(即来自命名空间Microsoft.Office.Interop.Excel的对象),但我已经看到它用于不同程度.
我想知道我是否可以逃避这样的事情:
var application = new ApplicationClass();
try
{
// do work with application, workbooks, worksheets, cells, etc.
}
finally
{
Marashal.ReleaseComObject(application)
}
Run Code Online (Sandbox Code Playgroud)
或者,如果我需要释放创建的每个对象,如此方法:
public void CreateExcelWorkbookWithSingleSheet()
{
var application = new ApplicationClass();
var workbook = application.Workbooks.Add(_missing);
var worksheets = workbook.Worksheets;
for (var worksheetIndex = 1; worksheetIndex < worksheets.Count; worksheetIndex++)
{
var worksheet = (WorksheetClass)worksheets[worksheetIndex];
worksheet.Delete();
Marshal.ReleaseComObject(worksheet);
}
workbook.SaveAs(
WorkbookPath, _missing, _missing, _missing, _missing, _missing,
XlSaveAsAccessMode.xlExclusive, _missing, …Run Code Online (Sandbox Code Playgroud) 我试图将Excel文件读入Data.DataTable列表,虽然使用我当前的方法可能需要很长时间.我特意按工作表逐个单元地去工作表,它往往需要很长时间.有更快的方法吗?这是我的代码:
List<DataTable> List = new List<DataTable>();
// Counting sheets
for (int count = 1; count < WB.Worksheets.Count; ++count)
{
// Create a new DataTable for every Worksheet
DATA.DataTable DT = new DataTable();
WS = (EXCEL.Worksheet)WB.Worksheets.get_Item(count);
textBox1.Text = count.ToString();
// Get range of the worksheet
Range = WS.UsedRange;
// Create new Column in DataTable
for (cCnt = 1; cCnt <= Range.Columns.Count; cCnt++)
{
textBox3.Text = cCnt.ToString();
Column = new DataColumn();
Column.DataType = System.Type.GetType("System.String");
Column.ColumnName = cCnt.ToString();
DT.Columns.Add(Column);
// Create row for …Run Code Online (Sandbox Code Playgroud) 我有一个应用程序调用
Email hello = new Email(appropriate constructor);
hello.Email_Send();
Run Code Online (Sandbox Code Playgroud)
我收到了例外:
由于以下错误,检索具有CLSID {0006F03A-0000-0000-C000-000000000046}的组件的COM类工厂失败:80080005服务器执行失败(HRESULT异常:0x80080005(CO_E_SERVER_EXEC_FAILURE)).
来自System.Runtime.InteropServices.COMException.
using O = Microsoft.Office.Interop.Outlook;
class Email
{
public void Email_Send()
{
O.Application outlook = new O.Application(); //Exception thrown here.
O.MailItem message = outlook.CreateItem(O.OlItemType.olMailItem);
message.To = Receiver;
message.CC = Sender;
message.Subject = Subject;
message.Body = "This is an automated message sent at " + DateTime.Now.ToString("HH:mm:ss") + " about " + Body_Topic + System.Environment.NewLine + Body_Content ;
message.Send();
}
}
Run Code Online (Sandbox Code Playgroud)
此错误以前从未发生过,并且我所知道的代码没有任何变化.http://support.microsoft.com/kb/825118似乎不符合我的症状 - 我的电脑没有停止响应等.任何诊断问题的帮助将不胜感激!
我刚刚开始通过C#调整Excel,以便能够自动创建,并添加到Excel文件中.
我可以打开文件并更新其数据并浏览现有的工作表.我的问题是如何添加新表?
我试过了:
Excel.Worksheet newWorksheet;
newWorksheet = (Excel.Worksheet)excelApp.ThisWorkbook.Worksheets.Add(
Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Run Code Online (Sandbox Code Playgroud)
但我得到COM异常,我的谷歌搜索没有给我任何答案.
来自HRESULT的异常:0x800A03EC来源是:"Interop.Excel"
我希望有人能够让我摆脱困境.
我正在编写VSTO Outlook添加,我需要保存插件从Web服务获取的一些设置.做这个的最好方式是什么.注册?VSTO插件是否可以完全访问这样做?也许包含设置的文件?
提前致谢.
我使用IIS 7.5在Windows 7 64位上运行C#ASP.NET 4.5 Web应用程序.它使用的应用程序池名为"ASP.NET v4.0",其标识为ApplicationPoolIdentity.该应用程序使用MS Office Interop(Microsoft Excel 14.0对象库).
在行wBook = wBooks.Add(Missing.Value);,它会引发以下错误:
由于没有足够的可用内存或磁盘空间,Microsoft Excel无法打开或保存更多文档.
u2022要提供更多可用内存,请关闭不再需要的工作簿或程序.
u2022要释放磁盘空间,请从您要保存的磁盘中删除不再需要的文件:Microsoft.Office.Interop.Excel.Workbooks.Add(Object Template)
1)我在DCOM配置中的MS Excel应用程序上给了帐户IIS apppool\ASP.NET v4.0完全控制.
2)我在'C:\ Windows\SysWOW64\config\systemprofile'上给了IIS apppool\ASP.NET v4.0完全控制,并在其中创建了一个Desktop文件夹.
3)我需要继续使用Interop,虽然不建议这样做.
4)该应用程序在Windows Server 2003/Windows XP 32位上正常工作.
5)计算机上安装了MS Office 2010(64位,试用版).
6)我不想改变应用程序.从ApplicationPoolIdentity到网络服务等的池标识.ApplicationPoolIdentity是IIS 7中新的标识类型,建议使用它.
如果我在DCOM配置中选择"交互式用户"(我已经以管理员身份登录),它可以正常工作,但它会导致其他问题.我需要使用"启动用户",这是ASP.NET v4.0.所以看起来这是一个许可问题.
请帮忙.谢谢.
iis-7 office-interop excel-interop asp.net-4.0 windows-7-x64
我遇到了经典场景,当在.NET中创建Word COM对象时(通过Microsoft.Office.Interop.Word程序集),即使我正确关闭并释放对象,WinWord进程也不会退出.
我已经将其缩小到使用Word.Documents.Add()方法.我可以在没有问题的情况下以其他方式使用Word(打开文档,修改内容等),并在我告诉它时退出WinWord.exe.一旦我使用Add()方法(并且仅在添加模板时),该过程就会继续运行.
这是一个简单的例子,它可以重现这个问题:
Dim word As New Word.Application()
word.Visible = False
Dim documents As Word.Documents = word.Documents
Dim doc As Word.Document = documents.Add(Template:=CObj(templatePath), NewTemplate:=False, DocumentType:=Word.WdNewDocumentType.wdNewBlankDocument, Visible:=False)
'' dispose objects
doc.Close()
While (Marshal.ReleaseComObject(doc) <> 0)
End While
doc = Nothing
While (Marshal.ReleaseComObject(documents) <> 0)
End While
documents = Nothing
word.Quit()
While (Marshal.ReleaseComObject(word) <> 0)
End While
word = Nothing
GC.Collect()
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我正在创建和正确处理对象,甚至采取额外的步骤来循环Marsha.ReleaseComObject,直到它返回正确的代码.在其他方面使用Word对象很好,只是那些讨厌的Documents.Add让我感到悲伤.是否有另一个在此过程中创建的对象需要引用和处理?我需要遵循另一个处理步骤吗?别的什么?非常感谢您的帮助 :)
Update: 我在处理步骤结束时尝试了GC.Collect,但仍然没有运气.
Update 2: 我已经将问题缩小到使用自定义模板.当我调用Documents.Add(...)时,我为新文档指定了一个自定义模板.如果我不这样做而是调用没有参数的Add(),那么问题就不会发生.
office-interop ×10
c# ×8
.net ×4
excel ×4
com ×3
interop ×2
.net-4.0 ×1
asp.net-4.0 ×1
automation ×1
c#-4.0 ×1
email ×1
iis-7 ×1
ms-word ×1
outlook ×1
outlook-2003 ×1
outlook-2010 ×1
vsto ×1
worksheet ×1