为什么我在尝试从后台工作者的进程中获取信息时会收到Win32Exception?

时间:2015-07-11 04:12:37

标签: c# .net winforms

DoWork活动:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            while (true)
            {
                if ((worker.CancellationPending == true))
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    Stopwatch sw = Stopwatch.StartNew();
                    PopulateApplications();
                    sw.Stop();
                    int msec = 1000 - (int)sw.ElapsedMilliseconds;
                    if (msec < 1) msec = 1;   // Don't consume 100% CPU
                    System.Threading.Thread.Sleep(msec);
                }
            }
        }

The PopulateApplications method:

private void PopulateApplications()
        {
            this.BeginInvoke(new MethodInvoker(delegate
            {
            var icon = Icon.ExtractAssociatedIcon(GetProcessInfo(GetProcessIntptr()).ProcessFileName);
            Image ima = icon.ToBitmap();
            ima = resizeImage(ima, new Size(25, 25));
            ima = (Image)(new Bitmap(ima, new Size(25, 25)));
            String status = GetProcessInfo(GetProcessIntptr()).ProcessResponding ? "Running" : "Not Responding";
            }));
        }

GetProcessInfo方法:

public ProcessInfo GetProcessInfo(IntPtr hwnd)
        {
            uint pid = 0;
            GetWindowThreadProcessId(hwnd, out pid);
            Process proc = Process.GetProcessById((int)pid);

            return new ProcessInfo
            {
                ProcessFileName = proc.MainModule.FileName.ToString(),
                ProcessName = proc.ProcessName,
                ProcessTitle = proc.MainWindowTitle,
                ProcessResponding = proc.Responding
            };
        }

最后一个ProcessInfo类:

public class ProcessInfo
        {
            public string ProcessName { get; set; }
            public string ProcessFileName { get; set; }
            public string ProcessTitle { get; set; }
            public bool ProcessResponding { get; set; }
        }

如果我在DoWork事件中调用方法PopulateApplications,如果我不调用该方法,我将得到异常,它不会抛出异常,我在我的程序中的其他地方使用GetProcessInfo只有当我从DoWork事件中调用它时,PopulateApplications方法才会抛出异常。

System.ComponentModel.Win32Exception was unhandled
  HResult=-2147467259
  Message=A 32 bit processes cannot access modules of a 64 bit process.
  Source=System
  ErrorCode=-2147467259
  NativeErrorCode=299
  StackTrace:
       at System.Diagnostics.NtProcessManager.GetModuleInfos(Int32 processId, Boolean firstModuleOnly)
       at System.Diagnostics.NtProcessManager.GetFirstModuleInfo(Int32 processId)
       at System.Diagnostics.Process.get_MainModule()
       at Automation.Form1.GetProcessInfo(IntPtr hwnd) in d:\C-Sharp\Automation\Automation\Automation\Form1.cs:line 573
       at Automation.Form1.<PopulateApplications>b__1() in d:\C-Sharp\Automation\Automation\Automation\Form1.cs:line 616
       at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
       at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
       at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       at System.Windows.Forms.Form.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at Automation.Program.Main() in d:\C-Sharp\Automation\Automation\Automation\Program.cs:line 19
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:

1 个答案:

答案 0 :(得分:1)

这是不可能的,因为没有“合法”的方法来管理来自32位应用程序的64位内存空间。 (内存管理模型,指针大小不同等方面存在一些差异。)

您应该将目标平台从x32(或mixed / anycpu)更改为x64。您可以在项目属性中执行此操作。