小编Mat*_*att的帖子

与SQLite的DLL地狱

我们的一些用户遇到了在运行时加载的sqlite.interop.dll版本的问题,这是一个真正令人头疼的问题.

背景:为AnyCPU构建的WPF应用程序,使用SQlite .NET和sqlite.interop.dll版本1.0.89进行部署.我们部署x86和x64 dll,并使用SQLite附带的延迟加载.直到最近,当我们开始从通常最近购买新戴尔机器的用户那里获得一些支持问题时,情况一直很好.似乎有一个旧版本的sqlite.interop.dll(v.1.0.80),不知何故,它的加载优先于我们发布的版本.我们得到的错误是缺少入口点'sqlite3_changes_interop'.

我们尝试过的:

  1. 将安装程序更改为在安装期间将相应的dll(x86/64)复制到与可执行文件相同的目录(即没有单独的x86/x64文件夹).这意味着我们不再使用延迟加载,因为可执行目录中提供了正确的dll(尽管我们没有在sqlite.net中明确禁用延迟加载机制).这不能解决问题..

  2. 应用程序首次加载时显式加载sqlite.interop.dll.同样,这似乎没有解决问题.

似乎dll加载位置的排序近年来有所改变,我可能没有很好的处理它.我总是假设可执行文件目录中的一个dll会得到第一个首选项,并且一个已经显式加载的dll会阻止在应用程序生命周期内重新加载相同的dll,所以对于我的生活,我无法理解这里发生了什么.

任何人都可以了解这里可能发生的事情吗?问题进一步复杂化的事实是我无法在本地重现问题 - 例如,在我的系统路径中放入错误的dll版本等.这让我觉得GAC可能会发挥作用?

真的坚持这个,所以任何帮助都会很棒.

另外 - 作为最后的手段 - 我可能会考虑恢复到相同的1.0.80版本,这样我们就不会遇到这个问题.有谁知道我们可以在哪里找到旧版本的sqlite.net和sqlite.interop.dll?

编辑 - 一些其他信息:

冲突是由与Dell Backup and Recovery一起安装的sqlite.interop.dll版本1.0.80的副本引起的.这安装在所有新戴尔计算机上,在这种计算机上安装我们软件的用户都遇到此问题.此Dell软件还使用System.Data.SQLite.dll.

正确版本的sqlite.interop.dll与我们的可执行文件位于同一目录中,我对dll加载的所有了解都表明应该优先加载它.

虽然我们还没有能够在本地重现该问题,但看起来interop.dll的错误版本不在路径上.此外,Dell备份实用程序在启动时自动运行.有没有人知道任何可能的机制,这可能会挂钩到DLL加载请求和提供错误的文件?

目前的思路是我们可以构建自己的System.Data.SQLite.dll并将interop加载代码更改为特定命名的版本(例如sqlite.interop.1.0.89.dll).不是一个很好的解决方案,但..

.net c# sqlite dll

22
推荐指数
1
解决办法
2093
查看次数

从ClickOnce迁移到MSI部署的策略

我们在市场上有一个使用ClickOnce部署的消费者应用程序.随着时间的推移,我们遇到过各种各样的问题,其中大部分都已经解决,但总是很遗憾没有使用简单的MSI安装程序.特别是我们希望能够提供适当的离线安装(从盒装副本),以及更好的多语言安装选项.在最终获得一些旧的32位dll依赖项后,我们刚刚将测试版更新为AnyCPU版本(在您提出之前 - 是的,我们的应用程序确实可以从内存地址空间的增加中受益,我们处理大量数据).现在我们当然意识到从x86到AnyCPU不适用于ClickOnce,因此它似乎是切换到另一种安装技术的理想时间.

这就是问题所在:我们希望从现有的ClickOnce安装中自动升级到新的安装程序.我们也非常希望保留用户设置(.config)文件.如果我们做不到,那就不是一个彻底的交易破坏者,但如果我们不这样做,它会激怒很多用户.

所以非常粗略的游戏规划是这样的:

创建应用程序的新版本并通过ClickOnce进行部署.这个新版本基本上是MSI安装程序的前端.它以某种方式抓取现有的用户设置,启动新安装程序的下载并调用它.然后,它将现有设置复制到新的应用程序目录.然后它卸载自己(本身就是以前的ClickOnce安装应用程序).

原则上我认为这可行,但我不确定如何去做.特别是将用户设置移动到新应用程序,并在最后自行卸载.

如果有人有任何提示,或经历过类似的过程,我会非常渴望听到它.

应用程序是针对.NET 4的c#.

谢谢,马特

.net clickonce

6
推荐指数
1
解决办法
414
查看次数

使用SharpDX在WPF中滚动图像时生涩的动画

我试图在WPF应用程序中通过SharpDX使用DirectX11在窗口中平滑地滚动一些图像.

一点背景:

图像是信号返回,随时间变化,从文件加载并作为纹理数组加载到D3D中,图像本身呈现为一系列纹理四边形(一系列相邻的矩形,在很长的水平线上) ).设置视口,使左右边缘表示时间偏移,并且信号显示在这些时间之间的时间段内.DirectX实现非常简单; 四个顶点生成一次,一个非常小的每帧缓冲区包含一个简单的2D世界视图变换,根据当前可见范围/缩放等更新缩放和平移.据我所知,D3D实现不是我遇到的问题的一部分 - 它确实是一个非常简单的设置,并且似乎渲染非常快(应该如此),虽然我确实有一些更好的东西(根据需要从磁盘传输纹理),但我有禁用所有这些并运行非常简单(小)纹理,而我尝试解决我遇到的问题..

问题:

当可见时间范围被动画化时,图像的滚动不平滑.图像在很多时候"抖动",坦率地看起来很糟糕(当它不抖动时,它看起来很棒).

设置:

DirectX渲染到D3DImage,在幕后进行一些工作以使DX11工作 - 此代码取自https://sharpdxwpf.codeplex.com/

有多个D3DImages(最多总共4个),排列在一个网格中(我已经测试了两个,两个都包含相同时间段的信号并一起动画).

这些D3DImages由DrawingVisual(由自定义FrameworkElement托管)绘制,它们被用作ImageBrush的源.frameworkelement对象根据需要触发渲染,绘图视觉处理D3D渲染调用并绘制一个矩形以使用D3DImage画笔填充控件.

使用WPF DoubleAnimation动画时间范围值.当前显示的视觉效果通过INotifyPropertyChanged绑定到此值,并在每次更改时触发渲染(通过InvalidateVisual).

DrawingVisual呈现代码,由"位置"值(可见时间范围的开始)的更改触发:

// update scene per-frame buffer first, with world-view transform
using (DrawingContext dc = RenderOpen()
{
    _scene.Renderer.Render(_draw_args);
    _image.Invalidate();

    dc.DrawRectangle(_brush, null, new Rect(viewer.RenderSize));
}
Run Code Online (Sandbox Code Playgroud)

我尝试过的:

我已经尝试过很多东西(并经过大量搜索)来尝试确定问题是由于抖动渲染请求计时,还是问题是否进一步进入渲染过程.

  1. 挂钩到CompositionTarget.Rendering首先通过CompositionTarget.Rendering驱动位置值的更新,并将剩余的进程保持原样(即元素对此值的更改做出反应):

(不用说,这是非常"测试"代码):

Stopwatch rsw;
long last_time = 0;
void play()
{
    rsw = new Stopwatch();
    last_time = 0;
    rsw.Start();
    CompositionTarget.Rendering += rendering;
}

void rendering(object sender, EventArgs e)
{
    double update_distance = rsw.ElapsedMilliseconds - last_time;
    Position += …
Run Code Online (Sandbox Code Playgroud)

wpf directx-11 managed-directx sharpdx

5
推荐指数
1
解决办法
887
查看次数

泛型类型的约束不能在IEnumerable中使用?

可能有一个问题,但我无法提出搜索条件来找到答案..

我可能在这里遗漏了一些明显的东西,但为什么我不允许这样做,这给出了错误:

"参数1:无法转换System.Collections.Generic.IEnumerable<TType>System.Collections.Generic.IEnumerable< Test.A>"

同时打电话给DoSomething?

public interface A
{
    void Foo();
}

public class B : A
{
    public void Foo()
    {
    }
}

class Test<TType> where TType : A
{
    public Test(IEnumerable<TType> testTypes)
    {
        DoSomething(testTypes);
    }

    void DoSomething(IEnumerable<A> someAs)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,这样做是可以的:

class Test
{
    public Test(IEnumerable<B> testTypes)
    {
        DoSomething(testTypes);
    }

    void DoSomething(IEnumerable<A> someAs)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

c#

5
推荐指数
1
解决办法
220
查看次数

标签 统计

.net ×2

c# ×2

clickonce ×1

directx-11 ×1

dll ×1

managed-directx ×1

sharpdx ×1

sqlite ×1

wpf ×1