الحصول على PID من مايكروسوفت وورد ApplicationClass؟

StackOverflow https://stackoverflow.com/questions/814936

  •  03-07-2019
  •  | 
  •  

سؤال

والنظر في هذا الرمز:

using Microsoft.Office.Interop.Word;

ApplicationClass _application = new ApplicationClass();

هل يمكنني الحصول على PID من عملية WINWORD.EXE التي أطلقتها _Application؟

وأنا في حاجة إلى PID لأنه مع ملفات فساد، أنا فقط لا يمكن إنهاء ApplicationClass، حتى باستخدام هذا الرمز:

_application.Quit(ref saveFile, ref missing, ref missing);
System.Runtime.InteropServices.Marshal.ReleaseComObject(_application);
GC.Collect();
GC.WaitForPendingFinalizers();

وأنا لا يمكن البحث عن عملية WINWORD.EXE وقتل، لأنه سوف يكون لي عدة، وأنا لا أعرف أي واحد أن يقتل. اذا كان يمكنني الحصول على PID لكل ApplicationClass، أنا فقط يمكن أن يقتل عملية WINWORD.EXE الصحيحة التي يتم إعطائي مشاكل الإقلاع عن التدخين.

هل كانت مفيدة؟

المحلول

وهنا هو كيف نفعل ذلك.

//Set the AppId
string AppId = ""+DateTime.Now.Ticks(); //A random title

//Create an identity for the app

this.oWordApp = new Microsoft.Office.Interop.Word.ApplicationClass();
this.oWordApp.Application.Caption = AppId;
this.oWordApp.Application.Visible = true;

while (GetProcessIdByWindowTitle(AppId) == Int32.MaxValue) //Loop till u get
{
    Thread.Sleep(5);
}

///Get the pid by for word application
this.WordPid = GetProcessIdByWindowTitle(AppId);

///You canh hide the application afterward            
this.oWordApp.Application.Visible = false;

/// <summary>
/// Returns the name of that process given by that title
/// </summary>
/// <param name="AppId">Int32MaxValue returned if it cant be found.</param>
/// <returns></returns>
public static int GetProcessIdByWindowTitle(string AppId)
{
   Process[] P_CESSES = Process.GetProcesses();
   for (int p_count = 0; p_count < P_CESSES.Length; p_count++)
   {
        if (P_CESSES[p_count].MainWindowTitle.Equals(AppId))
        {
                    return P_CESSES[p_count].Id;
        }
   }

    return Int32.MaxValue;
}

نصائح أخرى

قد يكون هناك بعض الخطأ في ملف Word. ونتيجة لذلك، عند فتح الملف مع Word.ApplicationClass.Documents.Open() الطريقة، سيكون هناك حوار أظهرت وسوف عملية معطلا.

استخدم Word.ApplicationClass.Documents.OpenNoRepairDialog() بدلا من ذلك. لقد وجدت أنها ثابتة المشكلة.

والطريقة المعتادة للحصول عليه هو تغيير عنوان كلمة إلى شيء فريد وقفز من خلال نافذة قائمة على مستوى عال حتى تجدها (EnumWindows).

http://www.codekeep.net/snippets /7835116d-b254-466e-ae66-666e4fa3ea5e.aspx

///Return Type: DWORD->unsigned int
///hWnd: HWND->HWND__*
///lpdwProcessId: LPDWORD->DWORD*
[System.Runtime.InteropServices.DllImportAttribute( "user32.dll", EntryPoint = "GetWindowThreadProcessId" )]
public static extern int GetWindowThreadProcessId ( [System.Runtime.InteropServices.InAttribute()] System.IntPtr hWnd, out int lpdwProcessId );


private int _ExcelPID = 0;
Process _ExcelProcess;

private Application _ExcelApp = new ApplicationClass();
GetWindowThreadProcessId( new IntPtr(_ExcelApp.Hwnd), out _ExcelPID );
_ExcelProcess = System.Diagnostics.Process.GetProcessById( _ExcelPID );

...

_ExcelProcess.Kill();

لا، للأسف لا توجد وسيلة لربط مثيل ApplicationClass مع عملية تشغيل من Word.

وماذا تحتاج لقتل مثيل وورد؟ لا يمكن أن تسأل فقط لإغلاق كافة وثائقها وبعد ذلك ببساطة التوقف عن استخدام تلك الحالة؟ إذا قمت بإزالة جميع الإشارات إلى فئة في نهاية المطاف ستبدأ في واتخاذ أسفل COM الخادم.

وقبل البدء في التطبيق الخاص بك، وقائمة جميع العمليات Word قيد التشغيل، بدء التطبيق الخاص بك، وقائمة تشغيل العمليات Word مرة أخرى. عملية جدت في القائمة الثانية والتي لا توجد في أول واحد هو الحق واحد:

var oPL1 = from proc in Process.GetProcessesByName("WINWORD") select proc.Id;
var app = new Word.Application();

var oPL2 = from proc in Process.GetProcessesByName("WINWORD") select proc.Id;
var pid = (from p in oPL2 where !oPL1.Contains(p) select p).ToList()[0];

وهذه الطريقة لديه مشاكل توقيت واضحة، لكنه هو الوحيد وجدتها الذي يعمل بشكل صحيح معظم الوقت.

enter code here  public void OpenWord(string Path, bool IsVisible)
    {

        MessageFilter.Register();
        object oMissing = Missing.Value;
        GUIDCaption = Guid.NewGuid().ToString();
        wordApp = new Microsoft.Office.Interop.Word.ApplicationClass();
        wordApp.Visible = IsVisible;
        wordApp.Caption = GUIDCaption;
        object oPath = Path;
        wordDoc = wordApp.Documents.Open(ref  oPath, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);

    }
    /// <summary>
    /// 关闭文件
    /// </summary>
    public void CloseWord()
    {
        object oMissing = Missing.Value;
        GUIDCaption = "";
        if (null != wordDoc)
        {
            wordDoc.Close(ref oMissing, ref oMissing, ref oMissing);
        }
        if (null != wordApp)
        {
            wordApp.Quit(ref oMissing, ref oMissing, ref oMissing);
        }
        MessageFilter.Revoke();
        GC.Collect();
        KillwordProcess();

    }
    /// <summary>
    /// 结束word进程
    /// </summary>
    public void KillwordProcess()
    {
        try
        {
            Process[] myProcesses;
            //DateTime startTime;
            myProcesses = Process.GetProcessesByName("WINWORD");

            //通过进程窗口标题判断
            foreach (Process myProcess in myProcesses)
            {
                if (null != GUIDCaption && GUIDCaption.Length > 0 && myProcess.MainWindowTitle.Equals(GUIDCaption))
                {
                    myProcess.Kill();
                }
            }
            MessageFilter.Revoke();
        }
        catch (Exception e)
        {
            throw e;
        }
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top