Click here to Skip to main content
15,881,172 members
Home / Discussions / C#
   

C#

 
AnswerRe: JSON Parsing Data Pin
Freak3028-Aug-14 23:00
Freak3028-Aug-14 23:00 
GeneralRe: JSON Parsing Data Pin
Alex.bordei29-Aug-14 2:43
Alex.bordei29-Aug-14 2:43 
QuestionC# connection between two SQLExpress servers on one machine Pin
Member 1103943928-Aug-14 18:44
Member 1103943928-Aug-14 18:44 
AnswerRe: C# connection between two SQLExpress servers on one machine Pin
Kornfeld Eliyahu Peter28-Aug-14 20:16
professionalKornfeld Eliyahu Peter28-Aug-14 20:16 
GeneralRe: C# connection between two SQLExpress servers on one machine Pin
Member 1103943928-Aug-14 20:28
Member 1103943928-Aug-14 20:28 
GeneralRe: C# connection between two SQLExpress servers on one machine Pin
Paul Conrad29-Aug-14 18:47
professionalPaul Conrad29-Aug-14 18:47 
AnswerRe: C# connection between two SQLExpress servers on one machine Pin
PIEBALDconsult2-Sep-14 8:24
mvePIEBALDconsult2-Sep-14 8:24 
QuestionUsing Process.Start on Excel Pin
mjackson1128-Aug-14 8:35
mjackson1128-Aug-14 8:35 
I am trying to use Process.Start to launch Excel. If I immediately grab the process returned by the Start method, any addins or extensions to Excel (xlls or xlam) will not work. If I wait until Excel finishes opening and loading all the addins, then grab the process, it works. Need them to work for this project.

I mashed up a class from code I found around to either grab a reference to an existing instance of Excel or to start a new one if it isn't running. Unfortunately, it doesn't work. If the Process.Start method is called, Excel starts loading. The WaitForInputIdle method waits for the message loop to start. But when the message loop starts, Excel is still loading things and has not created any child windows. So the class tries to enumerate the child windows but there are none. And I discovered that once you call EnumChildWindows() it "freezes" things in that it will not refer to a child window created subsequently even if you call it again after the child window is created. So loops to wait are out.

One solution is to recursively create new instances of the class to get around the EnumChildWindows problem, but I end up with 1000's of these instances.

As a kludge, I have a long Thread.Sleep in the code to wait until everything is open. It works correctly but I would like to know if there is a better way to determine if a process has finished opening, especially given the bug/feature in EnumChildWindows.

C#
public class ExcelInteropService
{
    private const string EXCEL_CLASS_NAME = "EXCEL7";

    private const uint DW_OBJECTID = 0xFFFFFFF0;

    private static Guid rrid = new Guid("{00020400-0000-0000-C000-000000000046}");

    public delegate bool EnumChildCallback(int hwnd, ref int lParam);

    [DllImport("Oleacc.dll")]
    public static extern int AccessibleObjectFromWindow(int hwnd, uint dwObjectID, byte[] riid, ref Microsoft.Office.Interop.Excel.Window ptr);

    [DllImport("User32.dll")]
    public static extern bool EnumChildWindows(int hWndParent, EnumChildCallback lpEnumFunc, ref int lParam);

    [DllImport("User32.dll")]
    public static extern int GetClassName(int hWnd, StringBuilder lpClassName, int nMaxCount);

    public static Microsoft.Office.Interop.Excel.Application GetExcelInterop(int? processId = null)
    {
        var p = processId.HasValue ? Process.GetProcessById(processId.Value) : Process.Start("excel.exe");
        p.WaitForInputIdle();
        System.Threading.Thread.Sleep(60000);
        Debug.Assert(p != null, "p != null");
        try {
            return new ExcelInteropService().SearchExcelInterop(p);
        }
        catch (Exception) {
            Debug.Assert(p != null, "p != null");
            return GetExcelInterop(p.Id);
        }
    }

    private bool EnumChildFunc(int hwndChild, ref int lParam)
    {
        var buf = new StringBuilder(128);
        GetClassName(hwndChild, buf, 128);
        if (buf.ToString() == EXCEL_CLASS_NAME) { lParam = hwndChild; return false; }
        return true;
    }

    private Microsoft.Office.Interop.Excel.Application SearchExcelInterop(Process p)
    {
        bool timeout = false;
        DateTime start = new DateTime();
        TimeSpan span = new TimeSpan();
        TimeSpan d = new TimeSpan(0, 1, 0);
        Microsoft.Office.Interop.Excel.Window ptr = null;
        int hwnd = 0;
        int hWndParent = 0;
        int hr = -1;

        Debug.Assert(p != null, "p != null");
        try {
            start = DateTime.Now;
            do {
                do {
                    i++;
                    hWndParent = (int)p.MainWindowHandle;
                    if (hWndParent == 0) {
                        Debug.WriteLine("MainWindowNotFound");
                        break;
                    }

                    EnumChildWindows(hWndParent, EnumChildFunc, ref hwnd);
                    if (hwnd == 0) {
                        Debug.WriteLine("ChildWindowNotFound");
                        break;
                    }

                    hr = AccessibleObjectFromWindow(hwnd, DW_OBJECTID, rrid.ToByteArray(), ref ptr);
                    if (hr < 0) {
                        Debug.WriteLine("AccessibleObjectNotFound");
                        break;
                    }
                    if (ptr != null)
                        return ptr.Application;
                } while (ptr == null);
                span = DateTime.Now - start;
                if (span > d)
                    timeout = true;
            } while (timeout == false);
        }
        catch (Exception ex) {
            Debug.Write("Search Exception - ");
            Debug.WriteLine(ex.Message);
            return null;
        }
        try {
            p.CloseMainWindow();
        }
        catch (Exception ex) {
            Debug.Write("CloseWinMain Exception = ");
            Debug.WriteLine(ex.Message);
        }
        return null;
    }
}

Mark Jackson

AnswerRe: Using Process.Start on Excel Pin
Richard Deeming28-Aug-14 9:59
mveRichard Deeming28-Aug-14 9:59 
GeneralRe: Using Process.Start on Excel Pin
mjackson1128-Aug-14 10:15
mjackson1128-Aug-14 10:15 
GeneralRe: Using Process.Start on Excel Pin
Richard Deeming29-Aug-14 1:41
mveRichard Deeming29-Aug-14 1:41 
GeneralRe: Using Process.Start on Excel Pin
mjackson1129-Aug-14 1:55
mjackson1129-Aug-14 1:55 
AnswerRe: Using Process.Start on Excel Pin
Bernhard Hiller28-Aug-14 21:15
Bernhard Hiller28-Aug-14 21:15 
QuestionInterop.Excel.Range query Pin
Dini Ngewu28-Aug-14 0:55
Dini Ngewu28-Aug-14 0:55 
AnswerRe: Interop.Excel.Range query Pin
Dini Ngewu28-Aug-14 0:59
Dini Ngewu28-Aug-14 0:59 
QuestionUnable to connect to the remote server when calling web services from code in 4.5 framework. Pin
Member 1101964328-Aug-14 0:48
Member 1101964328-Aug-14 0:48 
AnswerRe: Unable to connect to the remote server when calling web services from code in 4.5 framework. Pin
Gerry Schmitz28-Aug-14 5:28
mveGerry Schmitz28-Aug-14 5:28 
QuestionHow To Use Guid Filter in Select StateMent :( :( :( Pin
mhd.sbt27-Aug-14 19:42
mhd.sbt27-Aug-14 19:42 
AnswerRe: How To Use Guid Filter in Select StateMent :( :( :( Pin
V.28-Aug-14 1:48
professionalV.28-Aug-14 1:48 
GeneralRe: How To Use Guid Filter in Select StateMent :( :( :( Pin
mhd.sbt28-Aug-14 7:54
mhd.sbt28-Aug-14 7:54 
GeneralRe: How To Use Guid Filter in Select StateMent :( :( :( Pin
V.28-Aug-14 19:18
professionalV.28-Aug-14 19:18 
AnswerRe: How To Use Guid Filter in Select StateMent :( :( :( Pin
Richard Deeming28-Aug-14 1:49
mveRichard Deeming28-Aug-14 1:49 
GeneralRe: How To Use Guid Filter in Select StateMent :( :( :( Pin
mhd.sbt30-Aug-14 4:37
mhd.sbt30-Aug-14 4:37 
QuestionProgress Bar makes copying painfully slow, a little help please? Pin
kiasta27-Aug-14 17:26
kiasta27-Aug-14 17:26 
AnswerRe: Progress Bar makes copying painfully slow, a little help please? Pin
Ravi Bhavnani27-Aug-14 17:44
professionalRavi Bhavnani27-Aug-14 17:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.