如何使用silverlight加载动态库(dll)并发布到IIS7

n  开发环境搭建

本程序采用Visual Studio 2010 Ultimate+ Silverlight 4为开发环境,VS 2010下载地址参考\\192.168.75.5\共享软件\常用软件\visual studio,安装方法不再详述,Silverlight4_Tools下载地址参考http://www.microsoft.com/downloads/zh-cn/details.aspx?FamilyID=b3deb194-ca86-4fb6-a716-b67c2604a139

1.   安装VS2010

2.   安装Silverlight4_Tools

安装时如果遇到如下错误:


请不要灰心,将Silverlight4_Tools.exe改为Silverlight4_Tools.zip,则可以发现这就是一个压缩包,文件内容如下:


l  首先安装VS10-KB982218-v4.exe

l  接着安装silverlight_sdk.msi

l  再安装Silverlight_Developer.exe

为了验证Silverlight是否已经安装成功,打开VS2010,单击File->New->Project->Visual C#,选择Silverlight Application,如图:


一路往下:


打开MainPage.xaml.cs,在InitializeComponent行设置断点,


按下F10,看看是否能够调试,如果有错误提示,则说明安装的Silverlight的Developer和RunTime版本不一致,请下载Silverlight Developer 和RunTime运行时库,本才程序使用的版本为4.0.605310,有需要者可联系([email protected]),如果提示不能安装,则将先前安装的版本卸载后重新安装。4.0.608310下载地址为(http://222.218.45.50:82/down/Silverlight.zip),至此,silverlight开发环境搭建完毕。


n  创建动态库

首先,为了测试Silverlight加载动态库,我们打开VS 2010,编一个动态库出来,步骤如下:File->New->Project->Visual C++->Win32 ConsoleApplication,将工程命名为load_dll,如图:


单击ok,单击Next,在Application Settings选择Dll,如图:


单击Finish,完成动态库的创建。为了测试,我们在load_dll.cpp文件中添加两个函数,命名为add_number,sub_number,代码如下:


选择工程load_dll,右键->Add->New Item->Visual C++->Code->Module- DefinitionFile,将其命名为load_dll,如图


单击Add,添加如下代码:


单击Build->Build Solution,完成动态库的创建。

n  Silverlight之加载动态库

打开VS 2010,单击File->New->Project->Visual C#->Silverlight Application,将工程命名为load_dll,如图:


在弹出的对话框中单击OK


完成load_dll工程的创建。打开load_dll.Web下的ClientBin目录,将先前创建的load_dll.dll文件拷贝 到ClientBin目录下,选择ClientBing,右键->Add->Exist Item选择拷贝过来的load_dll.dll,将其添加到ClientBin目录中。为了能够在工程中加载动态库,右键load_dll.Web->Add->New Item,在弹出的对话框中选择Online Templates->选择Web Service,命名为WebService1.asmx,如图:


单击Add,完成asmx文件的添加。

在WebService1.asmx.cs文件中添加如下代码:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Services;

using System.Runtime.InteropServices;

namespace load_dll.Web

{

    /// <summary>

    /// Summary description for WebService1

    /// </summary>

    [WebService(Namespace= "http://tempuri.org/")]

    [WebServiceBinding(ConformsTo= WsiProfiles.BasicProfile1_1)]

    [System.ComponentModel.ToolboxItem(false)]

    // To allow thisWeb Service to be called from script, using ASP.NET AJAX, uncomment thefollowing line.

    //[System.Web.Script.Services.ScriptService]

    public class WebService1: System.Web.Services.WebService

    {

        const string DllPath = "G:/learn/silverlight/load_dll/load_dll.Web/ClientBin/load_dll.dll";

        [WebMethod]

        public string HelloWorld()

        {

            return"Hello World";

        }

        [WebMethod]

        public int SLAddNumber(inta, int b)

        {

            returnadd_number(a, b);

        }

        [WebMethod]

        public int SLSubNumber(inta, int b)

        {

            returnsub_number(a, b);

        }

        [DllImport(DllPath,CharSet = CharSet.Ansi, EntryPoint = "add_number", ExactSpelling = false)]

        public extern intadd_number(int a, intb);

        [DllImport(DllPath,CharSet = CharSet.Ansi, EntryPoint = "sub_number", ExactSpelling = false)]

        public extern intsub_number(int a, intb);

    }

}

可以看出DllPath被设置为绝对路径,为什么这么设后面再说。右键load_dll.Web->Build,如果没有出现错误则表示成功了一半,这个一定要编译,否则下面的工作无法继续,选中load_dll工程,右键->Add Service Reference,如图:


单击Discover,将自动列出WebService.asmx,双击MainPage.xaml,在Form上添加两个按钮,一个设为相加,一个设为相减,并分别双击,添加如下代码:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using load_dll.ServiceReference1;

namespace load_dll

{

    public partial class MainPage : UserControl

    {

        publicMainPage()

        {

            InitializeComponent();

        }

        privatevoid button1_Click(objectsender, RoutedEventArgs e)

        {

            //创ä¡ä建¡§webService代䨲理¤¨ª类¤¨¤的Ì?对?象¨®实º¦Ì例¤y

            WebService1SoapClientsclient = new WebService1SoapClient();

            sclient.SLAddNumberAsync(100, 50);

            sclient.SLAddNumberCompleted += new EventHandler<SLAddNumberCompletedEventArgs>(show_add);

        }

        public void show_add(objectsender, SLAddNumberCompletedEventArgs e)

        {

            MessageBox.Show((e.Result).ToString());

        }

        privatevoid button2_Click(objectsender, RoutedEventArgs e)

        {

            //创ä¡ä建¡§webService代䨲理¤¨ª类¤¨¤的Ì?对?象¨®实º¦Ì例¤y

            WebService1SoapClientsclient = new WebService1SoapClient();

            sclient.SLSubNumberAsync(100, 50);

            sclient.SLSubNumberCompleted += new EventHandler<SLSubNumberCompletedEventArgs>(show_sub);

        }

        public void show_sub(objectsender, SLSubNumberCompletedEventArgs e)

        {

            MessageBox.Show((e.Result).ToString());

        }

    }

}

按下F7键,编译成功后,CTRl+F5运行即可看到如下效果:


n  Silverlight之IIS的安装

为了能够运行ASP.NET服务,需要在部署机器上安装IIS服务,这里只说明如何在Windows 7上安装IIS服务,方法如下:

单击开始->控制面板->程序->打开或关闭windows功能,在弹出的对话框上选择Internet信息服务->万维网服务->应用程序开发功能->ASP.NET,如图:


Windows 7 系统上安装好IIS 服务后,默认就支持.asmx,和.xaml扩展名的文件,在XP系统上或者Server机器上部署IIS时,还需添加对上述两种扩展名的支持,具体可用IIS 和MIME为关键字搜索即可获得方法。在浏览器输入:http://127.0.0.1,如果出现IIS的欢迎界面,则说明IIS服务安装成功。右键我的电脑->管理->服务和应用程序->Iternet 信息服务,可以看到IIS已经为我们创建好了一个DefaultWeb Site站点。

n  Silverlight之发布

前面,我们已经完成了名为load_dll的Silverlight工程,现在我们要将其部署到IIS服务站点,还记得上面说过的动态库的加载路径的问题,这里我们不能写为绝对路径,需要设置为虚拟的路径,这样客户端在访问服务端时才能访问加载到这个动态库,将先前的代码修改如下:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Services;

using System.Runtime.InteropServices;

namespace load_dll.Web

{

    public class DllInvoke

    {

        [DllImport("kernel32.dll")]

        privateextern static IntPtr LoadLibrary(Stringpath);

        [DllImport("kernel32.dll")]

        privateextern static IntPtr GetProcAddress(IntPtrlib, String funcName);

        [DllImport("kernel32.dll")]

        privateextern static bool FreeLibrary(IntPtrlib);

        public Delegate Invoke(StringAPIName, Type t)

        {

            IntPtrapi = GetProcAddress(hLib, APIName);

            return(Delegate)Marshal.GetDelegateForFunctionPointer(api,t);

        }

        privateIntPtr hLib;

        publicDllInvoke(String DLLPath)

        {

            hLib = LoadLibrary(DLLPath);

        }

        ~DllInvoke()

        {

            FreeLibrary(hLib);

        }

    }

    /// <summary>

    /// Summary description for WebService1

    /// </summary>

    [WebService(Namespace= "http://tempuri.org/")]

    [WebServiceBinding(ConformsTo= WsiProfiles.BasicProfile1_1)]

    [System.ComponentModel.ToolboxItem(false)]

    // To allow thisWeb Service to be called from script, using ASP.NET AJAX, uncomment thefollowing line.

    //[System.Web.Script.Services.ScriptService]

    public class WebService1: System.Web.Services.WebService

    {

        public delegate int Proc_add_number(inta, int b);

        public delegate int Proc_sub_number(inta, int b);

       

       // conststring DllPath ="G:/learn/silverlight/load_dll/load_dll.Web/ClientBin/load_dll.dll";

        [WebMethod]

        public string HelloWorld()

        {

            return"Hello World";

        }

        [WebMethod]

        public int SLAddNumber(inta, int b)

        {

            DllInvokeinvoke = new DllInvoke(Server.MapPath(@"~/ClientBin/load_dll.dll"));

            Proc_add_numberadd_number = (Proc_add_number)invoke.Invoke("add_number", typeof(Proc_add_number));

            returnadd_number(a, b);

        }

        [WebMethod]

        public int SLSubNumber(inta, int b)

        {

            DllInvokeinvoke = new DllInvoke(Server.MapPath(@"~/ClientBin/load_dll.dll"));

            Proc_sub_numbersub_number = (Proc_sub_number)invoke.Invoke("sub_number", typeof(Proc_sub_number));

            returnsub_number(a, b);

        }

        //[DllImport(DllPath,CharSet = CharSet.Ansi, EntryPoint = "add_number", ExactSpelling =false)]

        //publicstatic extern int add_number(int a, int b);

        //[DllImport(DllPath,CharSet = CharSet.Ansi, EntryPoint = "sub_number", ExactSpelling = false)]

        //publicstatic extern int sub_number(int a, int b);

    }

}

通过使用Server.MapPath(@"~/ClientBin/load_dll.dll")就可以将虚拟路径转换为物理路径了。打开ServiceReferences.ClientConfig,将

<endpoint address="http://localhost:62429/WebService1.asmx" binding="basicHttpBinding"

                bindingConfiguration="WebService1Soap" contract="ServiceReference1.WebService1Soap"

                name="WebService1Soap" />

修改为

<endpoint address="http://192.168.202.168/WebService1.asmx" binding="basicHttpBinding"

                bindingConfiguration="WebService1Soap" contract="ServiceReference1.WebService1Soap"

                name="WebService1Soap" />

其中,192.168.202.168为我的IIS服务地址,对应的修改即可。右键load_dll.Web->Publish,弹出的对话框中填入如下信息


ServiceURL为本机地址,即IIS所在的机器,Site/application为缺省站点名,单击Publish,即可完成站点发布。

本程序的源码我已经上传到我的资源中,下载地址为http://download.csdn.net/my/uploads,如果有需要可以跟我联系QQ:540331240

猜你喜欢

转载自blog.csdn.net/lxf20054658/article/details/6923604