0

私も書いているDLLにフックしているWPFアプリケーションがあります。DLL は、サードパーティ アプリケーションのデータ フォルダをスキャンし、内部のデータのすべての解釈を処理します。WPF は、その上に優れた GUI を提供することです。将来的にはコマンド ライン インターフェイスも作成する必要があるかもしれないので、それらを分離しました。

データ フォルダのスキャンには時間がかかるため、オブジェクト (リポジトリ) の状態を保存し、データ フォルダがスキャンされて同じ「最終変更」状態を保持している場合は、代わりにそれを開きたいと考えました。リポジトリ オブジェクトを [Serializable] としてマークしましたが、(WPF または DLL から) 状態を保存しようとすると、WPF MainWindow が [Serializable] ではないという例外が発生します。

作成された .dat ファイルを読むと、そのクラスからの情報がいくつか (すべてではない) 含まれています。

WPF ウィンドウに関する情報を保存しようとする理由がわかりません。ウィンドウを [Serializable] としてマークしようとしましたが、そのクラスでは許可されていません。アプリケーションと一緒に DLL をロードしているので、Web を検索すると AppDomains を調べることができましたが、それは私の頭を少し超えています。以下は、私が現在それを実装しようとしている方法です。編集:シリアル化の呼び出しは、WPF コードの下部にあります。

WPF 名前空間内にインライン クラスを作成し、それをファイルに正常にシリアル化できたことに言及する必要があります。

どんな助けでも大歓迎です。

これはDLLです:

namespace HPOO_XML_Parser
{
[Serializable]
public class HPOORepository
{

    string _version;
    string _path;
    string _library;
    string _uuid;


    [NonSerialized]
    BackgroundWorker bWorker = new BackgroundWorker();
    [NonSerialized]
    XElement _xmlRepo;      


    int _nodeCount;
    List<Node> nodes;
    ...
    Rest of properties and methods
}

そしてそれを呼び出すWPF

namespace HPOO_Repository_Scanner
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    HPOORepository repo;

    public MainWindow()
    {
        InitializeComponent();
        StatusVisibility(); // Simply hides progress bar/cancel button
    }

    private void OpenRepository(object sender, RoutedEventArgs e)
    {

        string ooHome;
        using (FolderBrowserDialog browser = new FolderBrowserDialog())
        {
            ooHome = Environment.GetEnvironmentVariable("ICONCLUDE_HOME");
            if (ooHome != null)
            {
                browser.SelectedPath = ooHome;
            }
            browser.ShowNewFolderButton = false;
            browser.Description = "Select a repository to open...";

            if (browser.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                try
                {
                    repo = new HPOORepository(browser.SelectedPath);
                }
                catch (Exception ex)
                {
                    System.Windows.MessageBox.Show(ex.Message, "Invalid Repository Selected", MessageBoxButton.OK, MessageBoxImage.Error);

                }
            }
            repo.ProgressChanged += new ProgressChangedEventHandler(repo_ProgressChanged);

            prgStatus.Maximum = 100;

            repo.ReadRepository();

        }

    }
private void mnuSave_Click(object sender, RoutedEventArgs e)
    {
        SaveRepo(repo);
    }

    public void SaveRepo(object repository)
    {
        BinaryFormatter binFormat = new BinaryFormatter();

        using (Stream fStream = new FileStream("test" + ".dat",
            FileMode.Create, FileAccess.Write, FileShare.None))
        {
            binFormat.Serialize(fStream, repository);
        }
    }

編集:そして最後に例外:

System.Runtime.Serialization.SerializationException was unhandled
Message=Type 'HPOO_Repository_Scanner.MainWindow' in Assembly 'HPOO Repository Scanner, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
Source=mscorlib
StackTrace:


    at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
       at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context)
       at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
       at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
       at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
       at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo)
       at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
       at HPOO_Repository_Scanner.MainWindow.SaveRepo(Object repository) in \\tsclient\D\Dropbox\_Work\Visual Studio Projects\HPOO Repository Scanner\HPOO Repository Scanner\HPOO Repository Scanner\MainWindow.xaml.cs:line 179
       at HPOO_Repository_Scanner.MainWindow.mnuSave_Click(Object sender, RoutedEventArgs e) in \\tsclient\D\Dropbox\_Work\Visual Studio Projects\HPOO Repository Scanner\HPOO Repository Scanner\HPOO Repository Scanner\MainWindow.xaml.cs:line 168
       at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
       at System.Windows.Controls.MenuItem.InvokeClickAfterRender(Object arg)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.DispatcherOperation.InvokeImpl()
       at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
       at 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 callback, Object state)
       at System.Windows.Threading.DispatcherOperation.Invoke()
       at System.Windows.Threading.Dispatcher.ProcessQueue()
       at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
       at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.Run()
       at System.Windows.Application.RunDispatcher(Object ignore)
       at System.Windows.Application.RunInternal(Window window)
       at System.Windows.Application.Run(Window window)
       at System.Windows.Application.Run()
       at HPOO_Repository_Scanner.App.Main() in \\tsclient\D\Dropbox\_Work\Visual Studio Projects\HPOO Repository Scanner\HPOO Repository Scanner\HPOO Repository Scanner\obj\x86\Debug\App.g.cs:line 0
       at System.AppDomain._nExecuteAssembly(Assembly 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.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 
4

2 に答える 2

0

XMLシリアライザーを使用していると仮定しています。シリアル化コードを表示する必要があります。また、例外が発生した場合は、例外とスタック トレースを表示します。この情報を使用してコンテキストを判断する方がはるかに簡単です。

その場合、[NonSerialized] 属性ではなく [XmlIgnore] を使用する必要があります。

于 2012-11-07T04:25:58.233 に答える
0

私は馬鹿みたいです。私は今朝それを理解することができました。

リポジトリ オブジェクトから ProgressChanged イベント ハンドラーを切り離す必要がありました。

オブジェクト作成時に付けた

repo.ProgressChanged += new ProgressChangedEventHandler(repo_ProgressChanged);

そして、オブジェクトの状態を保存する前に削除されました

private void mnuSave_Click(object sender, RoutedEventArgs e)
{
  repo.ProgressChanged -= repo_ProgressChanged;
  SaveRepo(repo);
}

同じ問題に遭遇した他の人に役立つことを願っています。

于 2012-11-08T00:27:53.743 に答える