4

我已经用 Visual Studio 2008 构建了一个 WPF 应用程序并为其创建了一个安装程序。到目前为止工作正常。我意识到它缺乏自动更新功能,在尝试了几种解决方案后,我决定尝试 clickonce 部署。经过在网络服务器上成功部署,我注意到安装下载的应用程序后应用程序崩溃。它抱怨这个:

无法创建在程序集“MyApplication,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”中定义的“Login”实例。调用的目标已引发异常。标记文件“MyApplication;component/login.xaml”第 1 行位置 9 中的错误。

这是堆栈跟踪

在 System.Windows.Markup.XamlParseException.ThrowException(字符串消息,异常 innerException,Int32 lineNumber,Int32 linePosition,Uri baseUri,XamlObjectIds currentXamlObjectIds,XamlObjectIds contextXamlObjectIds,Type objectType)
在 System.Windows.Markup.XamlParseException.ThrowException(ParserContext parserContext,Int32 lineNumber, Int32 linePosition, String message, Exception innerException) at System.Windows.Markup.BamlRecordReader.ThrowExceptionWithLine(String message, Exception innerException)
at System.Windows.Markup.BamlRecordReader.CreateInstanceFromType(Type type, Int16 typeId, Boolean throwOnFail)
在 System.Windows.Markup.BamlRecordReader.GetElementAndFlags(BamlElementStartRecord bamlElementStartRecord, Object& element, ReaderFlags& flags, Type& delayCreatedType, Int16& delayCreatedTypeId)
在 System.Windows.Markup.BamlRecordReader.BaseReadElementStartRecord(BamlElementStartRecord bamlElementRecord)
在 System.Windows.Markup.BamlRecordReader.ReadElementStartRecord (BamlElementStartRecord bamlElementRecord)
在 System.Windows.Markup.BamlRecordReader.ReadRecord(BamlRecord bamlRecord)
在 System.Windows.Markup.BamlRecordReader.Read(Boolean singleRecord)
在 System.Windows.Markup.TreeBuilderBamlTranslator.ParseFragment()
在 System.Windows.Markup .TreeBuilder.Parse()
在 System.Windows.Markup.XamlReader.LoadBaml(流流,ParserContext parserContext,对象父级,布尔 closeStream)
在 System.Windows.Application.LoadBamlStreamWithSyncInfo(流流,ParserContext pc)
在 System.Windows.Application.LoadComponent(Uri resourceLocator, Boolean bSkipJournaledProperties)
at System.Windows.Application.DoStartup()
at System.Windows.Application.<.ctor>b__0(Object used)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(对象源,委托回调,对象参数,布尔 isSingleParameter,委托 catchHandler)
在 System.Windows.Threading.Dispatcher.WrappedInvoke(委托回调,对象参数,布尔 isSingleParameter,委托 catchHandler)
在 System.Windows.Threading.DispatcherOperation.InvokeImpl() 在
System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(对象状态)
System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态)
在 System.Windows.Threading.DispatcherOperation.Invoke()
在 System.Windows.Threading.Dispatcher.ProcessQueue()
在 System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& 处理)
在 MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean&handled)
在 MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托回调, System.Windows.Threading.ExceptionWrapper.TryCatchWhen 处的对象 args,布尔 isSingleParameter)
(对象源,委托回调,对象 args,布尔 isSingleParameter,委托 catchHandler)
在 System.Windows.Threading.Dispatcher.WrappedInvoke(委托回调,对象参数,布尔 isSingleParameter,委托 catchHandler)
在 System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority 优先级,TimeSpan 超时,委托方法,对象参数,布尔 isSingleParameter)
在MS.Win32.HwndSubclass.SubclassWndProc
(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
在 MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
在 System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame 框架)
在 System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame 框架)
在 System.Windows.Threading.Dispatcher.Run()
在 System.Windows.Application.RunDispatcher(Object ignore)
在 System.Windows.Application.RunInternal(Window window)
在 System.Windows.Application.Run(Window window)
在 System .Windows.Application.Run()
在 myApplication.App.Main()

这只是调试器指向的区域

<Window x:Class="MyApplication.Login"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:src="clr-namespace:MyApplication"
    xmlns:UI="clr-namespace:UI;assembly=UI"
Title="My Application"  Height="400" Width="550" ResizeMode="NoResize" WindowStyle="ThreeDBorderWindow" WindowStartupLocation="CenterScreen" Name="Logine" Loaded="Logine_Loaded" Closed="Logine_Closed" Icon="orLogo.ico">

但是安装项目中的 msi 中的安装程序版本工作正常。所以我看不到错误来自哪里,因为我可以有设计视图。
问题1:有没有人有类似的问题,或者这是一个已知的问题?
问题 2:如果这是一个已知问题,那么还有什么可供选择的。我可能会放弃点击,但我的自动更新功能将丢失(因为没有我现在可以找到的不是过时或严重过时的) .
感谢您阅读本文并为我指明正确的方向。

4

1 回答 1

0

如果您转到 ClickOnce 缓存并找到应用程序的可执行文件并双击它,它仍然会失败吗?如果是这样,那么它本身就不是 ClickOnce 问题。可能是您在部署中缺少一些必需的程序集。或者您正在执行 ClickOnce 不允许的操作,例如访问需要管理权限的文件夹。

您也可以在构建后尝试从 \bin\release 文件夹中运行它,但这不会告诉您您的计算机上是否有一个您正在使用的程序集尚未部署。

Windows 7(和 vista)上的 ClickOnce 缓存位于:
C:\Users\username\AppData\Local\Apps\2.0\obfuscatedfolder\obfuscatedfolder

从那里,对于 win forms 应用程序,它会创建两个文件夹,一个名为 xxxx...exe_etc,另一个名为 xxxx...tion_etc... 以 xxxx_tion 开头的文件夹(其中 xxxx = 程序集名称的前四个字符)是运行应用程序的地方。我不确定 WPF 应用程序的文件夹名称是否相同,但希望它们不会太不同。可执行文件将仅位于一个文件夹中。(是的,你会认为它会在 xxxx...exe_etc 文件夹中,但事实并非如此。)

编辑——添加信息

对于丢失图像的问题:它们是否作为文件包含在项目中?如果是这样,请确保构建操作是“内容”并且“复制到输出目录”属性设置为“始终复制”。否则,它不会将它们包含在部署中。

对于数据库,同样的问题。它需要包含在项目中,并且必须相应地设置属性(将“复制...”设置为“如果较新则复制”)。另外,打开 Application Files 对话框,查看它是否标记为 Include(Data)。如果是,则将其部署到 Data 目录。如果您以这种方式部署它,当您发布新版本时,它会将数据复制到新文件夹中。您可以使用 ApplicationDeployment.DataDirectory 属性以编程方式找到它。

我通常不建议将您的数据信任给 ClickOnce。如果您将某些内容部署为数据,并且本地版本的日期/时间戳发生更改,ClickOnce 将部署新版本,并将旧版本放在名为 .\pre 的子文件夹中。对我来说,这很危险,因为您可能会意外修改数据。如果您只是打开数据库查看表结构,SQLCE 会更改日期/时间戳。所以我自己移动数据并处理数据库的更新。如果您想了解更多信息,请查看我的博客文章,了解如何保护您的数据免受 ClickOnce 更新的影响。

于 2010-05-28T21:05:59.263 回答