c#已使用中的工程
2009-10-09 17:16:00 cmiaomiaozoo 阅读数 930

C# 工程中使用 OPENSSL

                      C# C++/CLI 的结合

 

建议读者范围:有一定的 C#2.0 C 或者 C++ 的语言基础,并且对 .Net 互操作性有一定的了解

源程序下载地址: http://files.cnblogs.com/sleepingwit/Certificate.rar

总述

         OPENSSL 是一个开源的广为使用的开源信息安全 SDK ,然而该 SDK 的官方版本是用 C/C++ 语言编写的,因此该 SDK 的程序不能直接在 .Net 的虚拟机上运行。笔者最近的一个项目需要生成 PKCS#12 *.pfx )的数字证书 , 并且要提供 PKCS#12 证书到 X509(*.cer) 证书的转换功能 . 由于 .NET 的功能不够完善等诸多原因,笔者不能够很好的使用 .Net Framework 2.0 来完成上述功能。 OPENSSL 可以实现笔者需要的功能,但是无法做到与我们的 C# 程序交互,经过多次试验,笔者最终采用了 C# C++/CLI 结合的方式来实现上述功能—— C# 程序生成 pfx 证书并提供 pfx cer 证书的转换。

 

C++/CLI

         .Net Framework 2.0 中,微软将 Manage C++ 升级为 C++/CLI ,我们且不关注该改进的优缺点,在这里我们只关心我们需要的功能。 C++/CLI 之所以能够满足我们的需要,是因为他提供了一个很好的源代码级的 .Net 与本机代码的互操作功能。 .Net 与本机互操作可以有三种方式 [2]

         1 )基于 P/Invoke DLL 互操作;

         2 COM 互操作;

         3 C++ Interop.

第三种 C++ Interop C++/CLI 独有的源代码级在操作,该机制允许我们在有源代码的情况下轻松的高性能的实现本机( Native )与托管( .Net )程序的交互。当然,尽管 C++ Interop 是三者中性能最高的,但是在没有源代码的情况下是无法使用这中机制的。对于笔者的这个项目, C++ Interop 刚好能满足笔者的需要。

 

项目实例

Native C++ 使用 OPENSSL 生成数字证书

         笔者使用的 OPENSSL 版本为 0.9.8 下载页面为 http://www.openssl.org/source/

下载并编译好 OPENSSL 后导入我们的 C++ 工程中,我们使用如下的代码来生成证书

 

具体的源代码请参考附件





Code


/*
**********************************************************************************************************



FileName: CertificateCLI.h



Author: Lu Wei



CreateDate:2008-07-19



Description: class defination of certificate implement



*********************************************************************************************************

*/









#pragma
once





using

namespace
System;




using

namespace
System::Runtime::InteropServices;








namespace
CertificateCLI {








//
C++/CLI class implement certificate operation






static

class
CertificateNative



{




private
:



CertificateNative(){}




private
:








//
Generate Priva key , in this project it used for generate CA private key






static

int
GeneratePrivateKey(BYTE
*
bpPriKey,
int

*
ipPriKeyLen);




//
Generate PKCS#12 certificate






static

int
CreateP12FromPrivateKey(BYTE
*
bpCAPriKey,
int
iCAPriKeyLen,
int
iValidDay, BYTE
*
bpP12,
int

*
ipP12Len,
char

*
pszP12Pwd,
char
*
pszName,
char

*
pszSubjectName,
char

*
pszOrganizational,
char

*
pszOrganizationName,
char

*
pszEmail,
char

*
pszCountryRegion );




//
Export PKCS#12 information to X509 certificate






static

int
ParseP12Certificate(
char

*
szP12Pwd,BYTE
*
bpP12,
int
iP12Len,BYTE
*
bpOutCert,
int

*
ipCertLen);








public
:




//
mid-interface with .NET lanuguage and native C++














static

int
GenerateP12Certificate(
char
*
strName,
char
*
strOrganizational,
char
*
strOrganizationName,
char
*
strEmail,
char
*
strCountryRegion,
char
*
strPassword,
char
*
strSavePath);




static

int
ExportX509Certificate(
char
*
strSource,
char
*
strSavePath,
char
*
strPassword);







};








//
.NET class that supply Interface used by .Net language






public

ref

class
CertificateNet



{




private
:



CertificateNet(){}




public
:




static
System::Int32 GenerateP12Certificate(System::String
^
strName, System::String
^
strOrganizational, System::String
^
strOrganizationName, System::String
^
strEmail, System::String
^
strCountryRegion,



System::String

^
strPassword, System::String
^
strSavePath);




static
System::Int32 ExportX509Certificate(System::String
^
strSource,System::String
^
strSavePath,System::String
^
strPassword);



};







}









大家可以看到我使用了两个类来封装需要的功能,一个是 native C++ 类,用来实现 native C++ openssl 的交互,另一个是 C++/CLI 类,用来实现 Native C++ .Net Framework 的交互。从下面这小段代码可以看出我是如何做的交互( CertificateCLI.cpp ):

    对了,就是这个 static_cast <char *> 。实现了我们需要的功能,不过笔者的交互比较简单,如果需要更深入交互,可能带来更多的问题,比如内存泄露之类的,更深入的研究需要读者参考 MSDN 。现在我们来看看怎么在 C# 中使用它。




Code


System::Int32 CertificateNet::ExportX509Certificate(System::String
^
strSource, System::String
^
strSavePath, System::String
^
strPassword)



{



IntPtr ipSource

=
Marshal::StringToHGlobalAnsi(strSource);



IntPtr ipSavePath

=
Marshal::StringToHGlobalAnsi(strSavePath);



IntPtr ipPassword

=
Marshal::StringToHGlobalAnsi(strPassword);




char

*
szSource
=
static_cast
<
char
*>
(ipSource.ToPointer());




char

*
szSavePath
=
static_cast
<
char
*>
(ipSavePath.ToPointer());




char

*
szPassword
=
static_cast
<
char
*>
(ipPassword.ToPointer());







System::Int32 status

=
CertificateNative::ExportX509Certificate(szSource,szSavePath,szPassword);




return
status;







}





 

C# 中使用封装后的代码

         .Net 的公共语言接口( CLI )使得我们很容易能够用 C# 来调用上面的代码

 

    




Code


///

<summary>





///
Export PKCS#12 file to X509 certificate




///

</summary>





///

<param name="strSource">
the pfx file path
</param>





///

<param name="strSavePath">
where to save exported certificate
</param>





///

<param name="strPassword">
password
</param>





///

<returns></returns>






public

static

int
ExportP12Certificate(
string
strSource,
string
strSavePath,
string
strPassword)



{




int
status
=
CertificateNet.ExportX509Certificate(strSource, strSavePath, strPassword);




return
status;



}





这段代码显示了我们是如何调用 C++/CLI 生成的 DLL 中的方法。至此,我们实现了在 C# 工程中使用 OPENSSL

 

结束

         在笔者的项目中,只使用很小的一部分 OPENSSL 代码,因此维护起来较为容易,对于更复杂的代码,需要读者更加仔细。因为在 Visual Studio 2005 中,当你在写 C# 程序时,调式程序是不可以进入到 C++/CLI DLL 的源代码中去的,从而使得使用笔者的方法来使用 OPENSSL 时必须尽可能更加严格的保证 C++/CLI 写的 DLL 的不会出错。

附录

         [1] OPENSSL 的官方网站是 http://www.openssl.org/ ,如果读者想要进一步了解 OPENSSL 可以去访问,不过上面的资料较少, http://www.infosecurity.org.cn/forum/index.php 中国信息安全组织论坛上面有很多不错的资料,推荐给感兴趣的读者。笔者的项目中只用到了 OPENSSL 中很小的一个功能,冰山一角不足以窥全貌,有不足之处,望大家海涵。

         [2] .Net 互操作性的相关资料可以参考 MSDN, 笔者的资料来源于李建忠老师的 C++/CLI 视频讲座—— Visual C++ 2005 系列教 参考课程: VC++ 2005(9):非托管互操作    

[3] 由于博客园的文件大小限制,笔者无法提供编译好的 LIB 文件( OPENSSL ),不过所有的代码都在附件里面,笔者使用的是 Visual Studio 2005 SP1 编译 C++ C#


2018-05-08 12:16:19 imxiangzi 阅读数 2257

 Tesseract3.04是Tesseract目前最新的版本,该开源项目的家已经从Google Code搬到了Github。今天在VS2013的C#项目中简单验证了Tesseract3.04的功能,在这里记录一下,供有兴趣的同学参考。

1. 参考资源说明

      Tesseract开源项目:https://github.com/tesseract-ocr/tesseract,目前该项目中包含Tesseract3.04在java, android,VS等环境下的源码。

      Tesseract帮助文档:http://tesseract-ocr.github.io/,值得深入学习。

      A .Net wrapper for tesseract-ocr作者的Github:https://github.com/charlesw/

2. 在VS2013的C#工程中使用Tesseract3.04

       我仍然选择使用A .Net wrapper for tesseract-ocr来实现在VS2013的C#工程中使用Tesseract3.04,可以通过VS2013中的NuGet来安装该程序包。若有同学需要在C++工程中使用Tesseract3.04,可以在Tesseract在Github的仓库中下载VS相关工程自行编译。

2.1 在C#工程中使用NuGet安装A .Net wrapper for tesseract-ocr

      A .Net wrapper for tesseract-ocr作者在项目说明中有如下描述:

  Since tesseract and leptonica binaries are compiled with Visual Studio 2015 you’ll need to ensure you have the Visual Studio 2015 Runtime installed.

      这是一个重要的提醒:这个tesseract 的dll是使用vs 2015编译的,所以必须安装其发行包,同样分X64,X86两个版本,还是依赖于开发环境,不依赖于操作系统。

      因此如果开发环境是VS2013或者是VS2012,要想成功使用A .Net wrapper for tesseract-ocr,那么必须额外安装Visual Studio 2015 Runtime。

2.2 tessdata

      Tesseract3.04在识别文字时,需要有相应语言的字库文件,相应文件必须放在名为”tessdata”的文件夹中。字库的版本必须与tesseract的版本一致,Tesseract在Github的仓库中有各种语言的字库可以下载。

      我验证时用的是Github中Tesseract的英文字库,原始图片已经非常清晰了,但是识别结果一般般,也许字库的字体与待识别图片不一。


2.3 VS2013的C#工程中使用Tesseract3.04的实现代码

/* --------------------------------------------------------
 * author:livezingy
 * 
 * BLOG:http://www.livezingy.com
 * 
 * Development environment:
 *      Visual Studio V2013
 *      
 * Revision History:20160813 by livezingy
   
--------------------------------------------------------- */

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tesseract;

namespace Tesseract304Demo
{
    public partial class Form1 : Form
    {
        string imagePath;

        string tessdataPath;

        public Form1()
        {
            InitializeComponent();

            tessdataPath = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(System.IO.Directory.GetCurrentDirectory())));

            tessdataPath = tessdataPath + @"\tessdata\";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.InitialDirectory = "c:\\";
            openFileDialog.Filter = "All Image Files|*.bmp;*.ico;*.gif;*.jpeg;*.jpg;*.png;*.tif;*.tiff";
            openFileDialog.RestoreDirectory = true;
            openFileDialog.FilterIndex = 1;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                imagePath = openFileDialog.FileName;
                pictureBox1.Image = Image.FromFile(imagePath);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                using (var engine = new TesseractEngine(tessdataPath, "eng", EngineMode.Default))
                {
                    using (var img = Pix.LoadFromFile(imagePath))
                    {
                        using (var page = engine.Process(img))
                        {
                            richTextBox1.Text = page.GetText();
                        }
                    }
                }
            }
            catch (Exception error)
            {
            }
        }
    }
}

from: http://livezingy.com/tesseract3-04-demo-vs2013/


2018-12-29 22:53:03 u012842630 阅读数 66

C#工程点击启动时不自动重新生成
解决方案:
打开.sln对应项目的.csproj文件,删除如下图红色方框所示内容,重新加载项目即可
实例图片

2007-08-30 11:27:00 flashlm 阅读数 1698
            // Gets a reference to the same assembly that 
            
// contains the type that is creating the ResourceManager.
            System.Reflection.Assembly myAssembly;
            myAssembly 
= this.GetType().Assembly;

            
// Creates the ResourceManager.
            System.Resources.ResourceManager myManager = new 
                System.Resources.ResourceManager(
"TestPrintProcess.My"//我的资源文件是My.resources,程序集名称是TestPrintProcess
                myAssembly);

            
// Retrieves String and Image resources.
            System.String myString;
            System.Drawing.Image myImage;
            myString 
= myManager.GetString("flashlm");
            myImage 
= (System.Drawing.Image)myManager.GetObject("nopic.png");

            MessageBox.Show(myString);
            
this.pictureBox1.Image=myImage;

注:My.resources文件放在项目根目录上

创建和编辑资源文件 
.NET Framework 中包含一个称为 ResEditor 的示例应用程序,它可帮助您创建和编辑资源文件。ResEditor 应用程序使您可以创建二进制资源文件 (.resources) 以及 XML 资源文件 (.resX)。

生成 ResEditor
ResEditor 以源代码的形式随 .NET Framework SDK 一起提供。您必须先使用提供的批处理文件生成 ResEditor,然后才能使用它。

生成 ResEditor 应用程序

启动 Windows,然后单击“开始”按钮,指向“所有程序”,然后指向“Visual Studio .NET 2003”,再指向“Visual Studio .NET 工具”,最后选择“Visual Studio .NET 命令提示”,打开 Visual Studio .NET 命令提示。
在命令提示处,将目录更改为 SDK/v1.1/Samples/Tutorials/resourcesandlocalization/reseditor 文件夹,如下所示:
cd /Program Files/Microsoft Visual Studio .NET 2003/SDK/v1.1/Samples/Tutorials/resourcesandlocalization/reseditor

在命令提示处,键入 Build,然后按 ENTER 键以生成该应用程序。
ResEditor 已生成,并且可执行文件被放在 /Program Files/Microsoft Visual Studio .NET/FrameworkSDK/Samples/Tutorials/resourcesandlocalization/reseditor 文件夹中。

创建资源文件
生成 ResEditor 后,您可以使用它创建资源文件。

使用 ResEditor 创建资源文件

在 Windows 资源管理器中,浏览到包含 ResEditor 可执行文件的目录。
双击 ResEditor 图标启动该应用程序。
从“添加”下拉菜单中选择要添加的资源类型。
在“添加”文本框中键入资源的名称,然后单击“添加”按钮,将资源项添加到文件中。
在主窗格中,单击资源名称旁边的单元格以指定一个值。
对于“字符串”资源,在该框中键入相应的字符串。
对于“图像”和其他类型的资源,请浏览到相应的文件。
对于要添加到文件中的每个资源,重复步骤 3、4、5。
在“文件”菜单中,单击“另存为”以保存文件。您可以将文件保存为 .resources 文件,也可以保存为 .resX 文件。
编辑现有资源文件
您还可以使用 ResEditor 编辑现有资源文件。使用 ResEditor 既可编辑 .resources 文件也可编辑 .ResX 文件。

使用 ResEditor 编辑现有资源文件

在 Windows 资源管理器中,浏览到包含 ResEditor 可执行文件的目录。
双击 ResEditor 图标启动该应用程序。
在“文件”菜单上单击“打开”。
在“打开资源文件”对话框中浏览到相应的资源文件。
资源文件打开,并且它包含的资源显示在主窗格中。

如果要更改任何资源的值,请单击资源名称旁边的单元格并指定正确的值。
对于“字符串”资源,在该框中键入相应的字符串。
对于“图像”和其他类型的资源,请浏览到相应的文件。
如果要重命名资源,请执行以下操作:
通过单击要重命名的资源,突出显示它。
在“重命名”文本框中键入新名称。
单击“重命名”按钮,应用新名称。
如果要删除资源,请通过单击该资源将其突出显示,然后从“资源”菜单中选择“删除”。
编辑完资源文件后,选择“文件”,然后选择“另存为”以保存文件。

2008-01-09 22:33:00 flyskylf 阅读数 469
Assembly asm = Assembly.GetExecutingAssembly();
            Stream str 
= asm.GetManifestResourceStream(asm.GetName().Name+ "." + name);
            StreamReader reader 
= new StreamReader(str);
            
return reader.ReadToEnd();
 

1.工程里添加以下DLL:  2.

博文 来自: wangjijun0807
没有更多推荐了,返回首页