关于C#获取多个Excel.exe对象的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于C#获取多个Excel.exe对象的问题相关的知识,希望对你有一定的参考价值。

我现在是用做一个程序来判断excel的信息,比如文件名称,sheet的名称等等。
关键代码如上:
objApp = System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
oExcelApp = (Excel.Application)objApp;
现在遇到的问题时,有时候进程中会有多个“Excel.exe”。那么程序只会获取第一个对象,而我需要的是判断所有的对象。
求高手指教,哪怕是给个思路,急!高分悬赏,可以追加

http://www.codeproject.com/KB/COM/cominterop.aspx
codeproject上有一个类似的项目,是从ROT中获取activex对象的,可以参考.

我下载后稍微试验了一下,开两个文件名不同的excel,但一直取到同一个名称上,还不能实现你的效果
我的代码:
// System.Runtime.InteropServices

[DllImport("ole32.dll")]
public static extern int GetRunningObjectTable(int reserved,out System.Runtime.InteropServices.UCOMIRunningObjectTable prot);
[DllImport("ole32.dll")]
public static extern int CreateBindCtx(int reserved,out System.Runtime.InteropServices.UCOMIBindCtx ppbc);

private void btnDprocess_Click(object sender,EventArgs e)

List<object> list = new List<object>();
int numFetched;
UCOMIRunningObjectTable runningObjectTable;
UCOMIEnumMoniker monikerEnumerator;
UCOMIMoniker[] monikers = new UCOMIMoniker[1];
GetRunningObjectTable(0,out runningObjectTable);
runningObjectTable.EnumRunning(out monikerEnumerator);
monikerEnumerator.Reset();
while(monikerEnumerator.Next(1,monikers,out numFetched) == 0)

UCOMIBindCtx ctx;
CreateBindCtx(0,out ctx);
string runningObjectName;
monikers[0].GetDisplayName(ctx,null,out runningObjectName);
AInfo(runningObjectName);
Guid g = new Guid();
monikers[0].GetClassID(out g);
AInfo(g.ToString());
object runningObjectVal;
runningObjectTable.GetObject(monikers[0],out runningObjectVal);
list.Add(runningObjectVal);

for(int i = 0;i < list.Count;i++)

OfficeExcel._Application xls = list[i] as OfficeExcel._Application;
if(xls == null)
continue;
try

this.listBox1.Items.Add(i.ToString("D3")+"\t"+xls.Workbooks[1].Name);

catch



希望对你有参考价值

又查了一下,貌似你的需求是不可能实现的
"You can't connect to a "specific" instance of an application when using
GetActiveObject, if you need this you will have to create a new instance."
不能用GetActiveObject访问特定的应用程序实例,如果需要这样,只能创建新的实例.

No, you can only connect to the single instance that was registered in the
ROT. If you have 3 instances of the "same" server application running, you
will always connect to the first application that was started as this is the
one registered.
只能访问到ROT中注册的单一实例.如果有一个服务程序同时运行了三个实例,总是会访问到启动后的第一个注册实例
If you need a private instance you will need to create a new instance (using
.... = new Excel.ApplicationClass(); )and not connect to an instance that is
already running. This is the point of automation, you should not connect to
an instance started by an interactive user.
可以用new Excel.ApplicationClass创建一个私有的新实例,但不能访问运行中的
实例.这是Automation的机制....
Willy Denoyette [MVP]
http://bytes.com/topic/c-sharp/answers/272571-multiple-excel-processes追问

谢谢这位兄弟了,的确是麻烦。我现在是做一个excel的办公帮助系统(类似百度搜索的推荐),只是为了防止对无关excel的触发,所以需要对excel进程进行判断。但有时候有多个“Excel.exe”的时候就会导致不触发。
我知道GetActiveObject是不可能实现,所以想问问有没有别的什么思路,其实我自己做过一个用程序数组的
Process[] P
P= Process.GetProcessesByName("Excel");
这个就能获取多个进程了,但还获取不了每个进程对象

参考技术A using excel = Microsoft.Office.Interop.Excel; 命名空间
OpenFileDialog ofd = new OpenFileDialog();
用这个打开Excel
string filePath = ofd.FileName; 这个可以获取文件名
string [] arr = ofd.FileNames; 这个可以获取打开对话框中多个选择文件
excel.Worksheet sheet = (excel.Worksheet)app.Workbooks.Open(filePath).Worksheets[1];
这个可以获取到Sheet对象
参考技术B using excel = Microsoft.Office.Interop.Excel; 命名空间
OpenFileDialog ofd = new OpenFileDialog();
用这个打开Excel
string filePath = ofd.FileName; 这个可以获取文件名
string [] arr = ofd.FileNames; 这个可以获取打开对话框中多个选择文件
excel.Worksheet sheet = (excel.Worksheet)app.Workbooks.Open(filePath).Worksheets[1];
这个可以获取到Sheet对象
就想到这么多你可以在研究下追问

我要的是判断进程中的Excel而不是针对某个具体的文件,所以这个不是我要的

参考技术C //基于Office PIA的代码
Microsoft.Office.Interop.Excel.Application excelApp=new Microsoft.Office.Interop.Excel.Application();
excelApp.Workbooks这个东西就是你要找的,具体的还是去查msdn
用纯PIA吧,获得application对象直接new就行了,别用你现在这种不伦不类的代码,在本质上是一样的追问

老大啊,我要获取的是进程的对象,新建有什么用啊

追答

你先去查查pia的帮助之后再来继续提问,太自以为是的话,别人告诉你解决办法也白搭

参考技术D objApp = System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
此处"Excel.Application"指已注册的Excel编程标识符 (ProgID)
获得objApp后,应该指定objApp.workbooks[i]等相当于指定进程中每个exe
objApp.WorkBooks[i].Sheets[j]指定每个工作簿
具体请参照MSDN

以上是关于关于C#获取多个Excel.exe对象的问题的主要内容,如果未能解决你的问题,请参考以下文章

《C#高级编程》读书笔记:关于数组

关于C#委托应用与总结

为啥我的 Excel office 对象会留下 EXCEL.exe 进程? [复制]

MongoDB c#:关于分页的问题

如何释放为 Excel(C#)创建的对象 [重复]

C#关于反射创建泛型类