以下是我尝试在程序中打开OpenFileDialog时收到的错误消息:
“当前线程必须设置为单个 OLE之前的线程单元(STA)模式 可以打电话。确保你的 主要功能有STAThreadAttribute 标记在上面。这个例外只是 如果附加调试器则引发 过程。“
此错误消息的问题是我的Main方法是否附加了STAThread属性。我不知道如何处理这个问题。如果它已经存在,我怎么能添加一些东西。加倍它并不是一个好选择,我尝试删除它,构建应用程序,添加它并再次构建它没有成功。我只是不明白。
private void btnOldFind_Click(object sender, EventArgs e)
{
openFileDialog1.Multiselect = false;
openFileDialog1.FileName = "";
openFileDialog1.ShowHelp = false;
openFileDialog1.AutoUpgradeEnabled = true;
openFileDialog1.InitialDirectory = @"C:\";
openFileDialog1.Filter = "Microsoft Installer (*.msi)|*.msi|All Files (*.*)|*.* ";
openFileDialog1.FilterIndex = 1;
openFileDialog1.RestoreDirectory = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
textBoxOldInstallation.Text = openFileDialog1.FileName;
}
}
主要方法是:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
并没有明确地进行线程化。说实话,这只是一个非常基本的计划。
EDIT2 ::
这是完整的错误消息,包括调用堆栈
System.Threading.ThreadStateException未处理 Message =“在进行OLE调用之前,必须将当前线程设置为单线程单元(STA)模式。确保Main函数上标记了STAThreadAttribute。仅当调试器附加到进程时才会引发此异常。” 来源= “System.Windows.Forms的” 堆栈跟踪: 在System.Windows.Forms.FileDialog.RunDialog(IntPtr hWndOwner) 在System.Windows.Forms.CommonDialog.ShowDialog(IWin32Window所有者) 在System.Windows.Forms.CommonDialog.ShowDialog() 在MSI_Comparison_GUI.Form1.btnOldFind_Click(Object sender,EventArgs e)中的c:\ tfs \ DocuWare .NET \ DocuWare NewGen \ src \ Tools \ MSI_Comparison \ MSI_Comparison_GUI \ Form1.cs:第70行 在System.Windows.Forms.Control.OnClick(EventArgs e) 在System.Windows.Forms.Button.OnClick(EventArgs e) 在System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) 在System.Windows.Forms.Control.WmMouseUp(消息&amp; m,MouseButtons按钮,Int32点击) 在System.Windows.Forms.Control.WndProc(消息&amp; m) 在System.Windows.Forms.ButtonBase.WndProc(消息&amp; m) 在System.Windows.Forms.Button.WndProc(消息&amp; m) 在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp; m) 在System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp; m) 在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam) 在System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&amp; msg) 在System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID,Int32 reason,Int32 pvLoopData) 在System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason,ApplicationContext context) 在System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason,ApplicationContext context) 在System.Windows.Forms.Application.Run(Form mainForm) at c:\ tfs \ DocuWare .NET \ DocuWare中的MSI_Comparison_GUI.Program.Main()NewGen \ src \ Tools \ MSI_Comparison \ MSI_Comparison_GUI \ Program.cs:第18行 在System.AppDomain._nExecuteAssembly(Assembly assembly,String [] args) 在System.AppDomain.ExecuteAssembly(String assemblyFile,Evidence assemblySecurity,String [] args) 在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在System.Threading.ThreadHelper.ThreadStart_Context(对象状态) 在System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态) 在System.Threading.ThreadHelper.ThreadStart() InnerException:
答案 0 :(得分:14)
可能是您遇到Connect 1 上报告的以下问题:
根据该问题,当您同时拥有 myprogram.exe 和 myprogram时,会发生Visual Studio的托管过程,即myprogram.vshost.exe强制执行错误的公寓状态输出文件夹中的.dll 文件。
问题可能是特定于某些旧版本的Visual Studio(2005),我无法使用VS 2010重现它。
明显的解决方法是更改dll的名称或将dll移动到另一个文件夹。
由于您将项目的输出类型从类库更改为Windows应用程序,因此可能出现这种情况。
1 目前还不清楚这个问题是否得到了微软的确认,它只是说这个问题超出了VS产品团队的责任范围。
答案 1 :(得分:6)
你有一个不可能的堆栈跟踪。很明显,线程不是问题的原因,一切都在主线程上运行,Main方法的[STAThread]属性设置了单元状态。堆栈跟踪显示它确实是入口点。
好吧,坏消息,某种附加功能正在与你的主要线程相悖。做一些令人讨厌的事情,比如多次调用CoUninitialize。我曾经遇到过这种情况,花了我一个月才找到它。使用Project + Properties,Debug选项卡开始诊断,勾选“启用非托管代码调试”。这可以让你看到哪些DLL被加载到你的程序中,它显示在输出窗口中。
第一个引导是当对话框显示第一时间,但第二时间失败。然后你有一些shell扩展处理程序,它会进入你的程序。使用SysInternals的AutoRuns实用程序并禁用任何非Microsoft生成的shell扩展处理程序。
当对话框立即失败时会变得更难。然后使用Debug + Windows + Modules并浏览DLL列表。注意它们来自何处,显示在“路径”列中。不信任任何不像.NET或Microsoft DLL那样嘎嘎叫的东西。启用Microsoft Symbol Server时,特别是没有符号文件是一个主角。与此相关的一个好方法是将该列表与您在另一台没有此问题的计算机上看到的列表进行比较。
我确实有一个关于此的战争故事。我的COM代码在数百台机器上崩溃了,我所要做的只是一个小型机。花了我一个月的时间来发现一个名为ffdshow的开源项目。分布非常广泛,使用不同的名称。它有一个错误,两次调用CoUnitialize太多了。该漏洞存在于发布中两年,但在一年半前得到修复。 非常难以诊断,在我开始查看旧版本之前,我没有接近它。如果你在模块窗口中看到ffdshow,那么你就关闭了:)
祝你好运,让我们知道邪恶的行为者。答案 2 :(得分:3)
不能没有代码。如果是控制台应用程序,请在调用方法之前添加以下内容:
Console.Write(System.Threading.Thread.CurrentThread.ApartmentState);
否则,
MessageBox.Show(System.Threading.Thread.CurrentThread.ApartmentState);
看看线程公寓状态真的如此。
答案 3 :(得分:0)
尝试在主过程,创建对话框的位置以及使用位置设置断点。然后查看您实际所在的线程。另外,检查Thread.CurrentThread.GetApartmentState()
在这些点上的值。
答案 4 :(得分:0)
static void povprecje_stolpci(double matrix[][]) {
int i, j;
double zbir = 0, prosek = 0; // prosek - variable for average
for (i = 0; i < matrix.length; i++) {
for (j = 0; j < matrix[i].length; j++) {
zbir = (int) (zbir + matrix[i][j]); // zbir variable to calculate the sum of the elements in each
// columns
}
prosek = (int) (zbir / matrix[i].length); // average of the columns
System.out.print(prosek); // printing the average
zbir = 0; // setting the sum to 0 for the next element
System.out.print(" ");
}
}
上面的代码行对我有用。尝试一下。