C# 如何修复Word加载项中的内存泄漏
我有一个用VSTO编写的MS Word应用程序外接程序。它包含一个用于创建新信函文档的按钮。按下按钮时,将实例化文档,并显示一个WPF对话框以捕获信息,然后将信息插入文档中 在我的一台测试机器上,当在一个单词会话中创建大约40个字母时,我得到以下异常: 磁盘已满。在此驱动器上释放一些空间,或保存文档 在另一个磁盘上 请尝试以下一项或多项操作:C# 如何修复Word加载项中的内存泄漏,c#,wpf,memory-leaks,ms-word,vsto,C#,Wpf,Memory Leaks,Ms Word,Vsto,我有一个用VSTO编写的MS Word应用程序外接程序。它包含一个用于创建新信函文档的按钮。按下按钮时,将实例化文档,并显示一个WPF对话框以捕获信息,然后将信息插入文档中 在我的一台测试机器上,当在一个单词会话中创建大约40个字母时,我得到以下异常: 磁盘已满。在此驱动器上释放一些空间,或保存文档 在另一个磁盘上 请尝试以下一项或多项操作: 关闭所有不需要的文档、程序或窗口 将文档保存到另一个磁盘 因此,我使用任务管理器监视Winword.exe进程: 内存从97000K开始 内存随着每
- 关闭所有不需要的文档、程序或窗口
- 将文档保存到另一个磁盘
- 内存从97000K开始
- 内存随着每个字母文档的增加而稳步增加,直到在大约1000000K处看到错误
- 如果我关闭所有文档,内存只会下降到500000K
}您使用的是什么版本的VS?你能运行诊断工具吗?看。你调用了一些非托管代码吗?你可以尝试一些类似ANTS的东西(仅举一个例子)。有一个14天的测试版本可用。您可以看到哪些(托管)对象导致内存过高。我不知道它是否与office Add一起工作。我将尝试删除我的非托管代码,然后使用其中一个诊断工具。您使用的是什么版本的VS?你能运行诊断工具吗?看。你调用了一些非托管代码吗?你可以尝试一些类似ANTS的东西(仅举一个例子)。有一个14天的测试版本可用。您可以看到哪些(托管)对象导致内存过高。我不知道它是否与office Add一起工作。我将尝试删除我的非托管代码,然后使用其中一个诊断工具。
public class OfficeDialog : Window
{
[DllImport("user32.dll")]
static extern int GetWindowLong(IntPtr hwnd, int index);
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int width, int height, uint flags);
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam);
const int GWL_EXSTYLE = -20;
const int WS_EX_DLGMODALFRAME = 0x0001;
const int SWP_NOSIZE = 0x0001;
const int SWP_NOMOVE = 0x0002;
const int SWP_NOZORDER = 0x0004;
const int SWP_FRAMECHANGED = 0x0020;
const uint WM_SETICON = 0x0080;
const int ICON_SMALL = 0;
const int ICON_BIG = 1;
public OfficeDialog()
{
this.ShowInTaskbar = false;
//this.Topmost = true;
}
public new void ShowDialog()
{
try
{
var helper = new WindowInteropHelper(this);
using (Process currentProcess = Process.GetCurrentProcess())
helper.Owner = currentProcess.MainWindowHandle;
base.ShowDialog();
}
catch (System.ComponentModel.Win32Exception ex)
{
Message.LogWarning(ex);
//this.Topmost = true;
var helper = new WindowInteropHelper(this);
using (Process currentProcess = Process.GetCurrentProcess())
helper.Owner = currentProcess.MainWindowHandle;
base.ShowDialog();
}
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
RemoveIcon(this);
HideMinimizeAndMaximizeButtons(this);
//using (Process currentProcess = Process.GetCurrentProcess())
// SetCentering(this, currentProcess.MainWindowHandle);
}
public static void HideMinimizeAndMaximizeButtons(Window window)
{
const int GWL_STYLE = -16;
IntPtr hwnd = new WindowInteropHelper(window).Handle;
long value = GetWindowLong(hwnd, GWL_STYLE);
SetWindowLong(hwnd, GWL_STYLE, (int)(value & -131073 & -65537));
}
public static void RemoveIcon(Window w)
{
// Get this window's handle
IntPtr hwnd = new WindowInteropHelper(w).Handle;
// Change the extended window style to not show a window icon
int extendedStyle = OfficeDialog.GetWindowLong(hwnd, GWL_EXSTYLE);
OfficeDialog.SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_DLGMODALFRAME);
// reset the icon, both calls important
OfficeDialog.SendMessage(hwnd, WM_SETICON, (IntPtr)ICON_SMALL, IntPtr.Zero);
OfficeDialog.SendMessage(hwnd, WM_SETICON, (IntPtr)ICON_BIG, IntPtr.Zero);
// Update the window's non-client area to reflect the changes
OfficeDialog.SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
}
static void SetCentering(Window win, IntPtr ownerHandle)
{
bool isWindow = IsWindow(ownerHandle);
if (!isWindow) //Don't try and centre the window if the ownerHandle is invalid. To resolve issue with invalid window handle error
{
//Message.LogInfo(string.Format("ownerHandle IsWindow: {0}", isWindow));
return;
}
//Show in center of owner if win form.
if (ownerHandle.ToInt32() != 0)
{
var helper = new WindowInteropHelper(win);
helper.Owner = ownerHandle;
win.WindowStartupLocation = WindowStartupLocation.CenterOwner;
}
else
win.WindowStartupLocation = WindowStartupLocation.CenterOwner;
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsWindow(IntPtr hWnd);