开通专利申请的在线模式是一种巨大的进步,虽然仅仅只是创新工作上的一小步。经通周末两天两夜的"研发",终于把专利在线申请流程和软件搞明白了。此文适合于懂.NET C#、证书、控件等技术的人员阅读,也适合不懂这些技术的人员阅读。

"研发"专利申请软件的使用技术是一种非常辛苦的工作,所以我觉得有必要记录下来,以后每年清明节可以来此瞻仰和扫墓。我对CPC软件的评价也是中肯的:它不是一堆屎,因为不仅仅是一堆屎!

一、环境搭建

专利申请软件简称CPC客户端,无需登录即可使用,签名的时候指定证书即可,所以CPC实际上就是一个专利案卷编辑器,经过测试发现,CPC在XP下运行状况相对比较良好(仅此而已),按以下配置部署软件环境:

操作系统:WindowsXP

public static bool IsUnsupported =>((!IsWindowsXP && !IsWindows2003) && !IsWindows7);

.Net框架版本:最高3.5

IE版本:7、8、9(注:XP下无法安装IE9)

证书控件:http://interactive.cponline.cnipa.gov.cn/txnDownloadTl01.do?select-key:filename=OCX.zip

CPC客户端:http://cponline.sipo.gov.cn/nas/nas03/web/content/attachment/201202/14130914kpjg.rar

CPC更新程序:http://cponline.sipo.gov.cn/nas/nas03/web/content/attachment/201905/18095452b7az.zip

Office版本:2003或2007,高了不行

IE选项设置:给cponline.sipo.gov.cn和interactive.cponline.cnipa.gov.cn任何想要的权限,不得讲条件,包括但不限于允许未认证的控件下载或运行、加入信任站点、将安全等级能调多低就调多低。

你会问,没有XP怎么办?这个问题问得好,下载安装Oracle VM VirtualBox,虚拟一个XP。

二、安装软件及操作

安装CPC软件后根据自带说明安装更新程序,运行软件:

在网站http://cponline.sipo.gov.cn/注册一个个人或企业的账号,申请证书,整个流程网上申请网站的流程图是准确的。

由于IE下操作可能出现的问题多,对控件要求、安全要求也多,所以不在线上编译申请文件,全部在线下完成,但是证书也是要在网上下载的,必须。另外,要完整提交申请,线上必须用证书登录,但是一直没有办法使用证书登录,如下图:

不知道为什么检索不到证书,我查看源代码,它是用控件检索证书:

<object id="ctl" type="application/x-causn" width="0" height="0"><param name="onload" value="pluginLoaded" /><param name="onAddfile" value="onAddfile" />
</object>
//初始化数据jq(function() {pageSetup_RegSet();//获取登录地址func_getDwfwUri();//初始化设置账号登录验证码func_setDefaultCode(1);//控件初始化ctl.onInit();plugin = ctl;//初始化证书列表certs = plugin_GetCertificates(ctl);if (certs == null || certs.length == 0) {jq("#certificate").append("<option value='-1'>未检测到证书</option>");} else {for (var i = 0; i < certs.length; i++) {var cert = certs[i];var strCertNumber = cert.SerialNumber;var strCertCn = cert.CommonName + "";jq("#certificate").append("<option value='"+strCertNumber+"'>" + strCertCn+ "</option>");}}checkKeyType(jq('#certificate')[0]);});

查了一下,application/x-causn是指控件

就是“C:\Program Files (x86)\kairende\CA证书控件x86”下的那堆东西!

要是检索不到证书,分析代码就无能为力了,我保证,证书是安装了的。

由此可见,当时是用pfx文件安装的,它包含了私钥。可恨的是,当时安装证书的时候没有允许导出私钥,pfx文件找不到了,只能导出cer证书,这种证书没有带私钥,在别的电脑上后,也会检测不到证书。

回过头来,登录网站,下载证书!再啰嗦一下,切记保存pfx到硬盘,并且按照他的指示,保存到证书安装目录。

下载一次后,就不再允许下载了,这个坑让我废了两个证件号。如果你说没有废,请教我怎么重新下载证书!?我本以为作废证书以后就可以重新申请证书,然并卵!

三、制作专利申请文件

打开CPC客户端,设置网络服务器

选择一个能通的服务器。

经过测试,如果你勾选https,可能无法连接服务器。

证书管理,选择一个证书。

现在可以开始制作专利申请文件了,申请什么类型专利可以根据自己的需要选择。

进入案卷文件编辑器。

有两个钉子问题,需要单独拿出来说:

1.上传图片格式和尺寸问题

上CPC源代码先,怎么解决就不用多说了:

string str6 = Path.GetExtension(str3).Replace(".", "");if (str5 != str6){this.dtdErr = string.Concat(new object[] { "Validation", wj.WENJIANMC, "第", i + 1, "幅图片", innerText, "的文件类型与list.xml文件中的描述不一致!请重新编辑图片后再签名打包。", Environment.NewLine, this.dtdErr });}else if ((((str5.ToLower() != "jpg") && (str5.ToLower() != "jpeg")) && (str5.ToLower() != "tiff")) && (str5.ToLower() != "tif")){if ((wj.BEIZHU.ToUpper() != "PDF") || (str5.ToUpper() != "PDF")){this.dtdErr = string.Concat(new object[] { "Validation", wj.WENJIANMC, "第", i + 1, "幅图片", innerText, "是", str5, "格式!请插入jpg、jpeg、tiff或tif格式后再签名打包。", Environment.NewLine, this.dtdErr });}}else{box.Load(str3);image = box.Image;num2 = ((float.Parse(image.Width.ToString()) * 2.54) * 10.0) / ((double) image.HorizontalResolution);num = ((float.Parse(image.Height.ToString()) * 2.54) * 10.0) / ((double) image.VerticalResolution);if ((image.HorizontalResolution > 300f) || (image.VerticalResolution > 300f)){this.dtdErr = string.Concat(new object[] { "Validation", wj.WENJIANMC, "第", i + 1, "幅图片", innerText, " DPI大于300,请修改后再签名打包。", Environment.NewLine, this.dtdErr });str2 = "error";}else{if (str3.IndexOf("130001") >= 0){if ((num2 > 150.0) || (num > 220.0)){this.dtdErr = string.Concat(new object[] { "Validation", wj.WENJIANMC, "第", i + 1, "幅图片", innerText, "超出150mm x 220mm!请验证后再签名打包。", Environment.NewLine, this.dtdErr });str2 = "error";continue;}}else if ((num2 > 165.0) || (num > 245.0)){this.dtdErr = string.Concat(new object[] { "Validation", wj.WENJIANMC, "第", i + 1, "幅图片", innerText, "超出165mm x 245mm!请验证后再签名打包。", Environment.NewLine, this.dtdErr });str2 = "error";continue;}if (((str5 == "tif") || (str5 == "tiff")) && !clsImageHandle.IsCCITT4Image(str3)){this.dtdErr = string.Concat(new object[] { "Validation", wj.WENJIANMC, "第", i + 1, "幅图片", innerText, " 不是Group 4 压缩方式的TIF文件!请修改验证后再签名打包。", Environment.NewLine, this.dtdErr });str2 = "error";}}}

所以制作附图的时候,图片全部用灰度,不要用RGB模式,假如是300分辨率,图片宽<1948px,高小于3000px就行了, 至于其它分辨率,自己再根据上图公式去算一下吧。另外,如果你上传TIFF图片,要用Group 4压缩,用ACDSee10免费版就很好压缩。

2.签名失败问题

private bool Sign()
{StreamWriter writer;AnJuan aJ = this.SQLF.AJ;string path = Program.TEMP_ROOT_PATH + this.ZippedPath + @"zip\" + aJ.ANJUANBH.ToString() + ".zip";if (Settings.Default.IsRemPassword){string str2 = this.sign.SignFile(path);if (string.IsNullOrEmpty(str2)){return false;}writer = new StreamWriter(Program.TEMP_ROOT_PATH + this.ZippedPath + @"zip\" + aJ.ANJUANBH.ToString() + "_ca.txt", true);writer.WriteLine(str2);writer.Close();if (!this.sign.VerifyFile(path, str2)){return false;}return true;}string str4 = Program.TOOLS_ROOT_PATH + "testsign.exe";SignFileReturnClass class2 = this.sign.SignFile(path, str4, pub.GetIssuerDn());if (class2.ReturnCode != "00"){return false;}writer = new StreamWriter(Program.TEMP_ROOT_PATH + this.ZippedPath + @"zip\" + aJ.ANJUANBH.ToString() + "_ca.txt", true);writer.WriteLine(class2.ReturnString);writer.Close();if (!this.sign.VerifyFile(path, class2.ReturnString)){return false;}return true;
}

看到没,知道为什么签名错误了吧!?为此我写了一个小工具,验证一下签名看有什么问题,以下是代码片断:

public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){}private void button1_Click(object sender, EventArgs e){openFileDialog1.Title = "请选择有效的案卷文件(zip)";openFileDialog1.Filter = "案卷文件|*.zip";openFileDialog1.FileName = "";DialogResult dr = openFileDialog1.ShowDialog(this);if (dr == DialogResult.OK){bool rs = Sign(openFileDialog1.FileName);if (rs){label1.Text = "签名结果:" + rs.ToString();}}}private bool Sign(string path){try{FileInfo file = new FileInfo(path);string aj = file.Name.Substring(0, file.Name.Length - 4);StreamWriter writer;listBox1.Items.Add("开始准备签名...");listBox1.Items.Add("Path..." + path);SignClass sign = new SignClass(GetIssuerDn());bool s1 = sign.SetCurrentCert(0);listBox1.Items.Add("证书数..." + sign.GetCertsCount());listBox1.Items.Add("设置当前证书..." + s1.ToString());string str2 = sign.SignFile(path);listBox1.Items.Add("签名值长度..." + str2.Length);if (string.IsNullOrEmpty(str2)){listBox1.Items.Add("签名错误代码:" + sign.cur_cert.GetLastErr());return false;}writer = new StreamWriter(file.DirectoryName + "\\" + aj + "_ca.txt", true);writer.WriteLine(str2);writer.Close();if (!sign.VerifyFile(path, str2)){listBox1.Items.Add("验证签名...失败!");return false;}return true;}catch (Exception ex){listBox1.Items.Add("签名异常..." + ex.ToString());return false;}}private string GetIssuerDn(){return "CN=国家知识产权局CA证书, OU=国家知识产权局, O=国家知识产权局, L=BeiJing, S=BeiJing, C=CN";}private string GetIssuerDn_CN(){return "国家知识产权局CA证书";}}

我可以再完善一下,使用  testsign.exe 再测试一下,这货应该能够返回为什么不能签名成功,懒得试了,谁有空谁试!

过了五分钟,强迫症发作了。。。

你们不用试了,代码跟SignClass一样,也不知道是谁抄谁!

   using DS20SignLib;using SignTest.Utility;using System;using System.Collections.Generic;using System.Diagnostics;using System.IO;public class SignClass{private IDS20SignCtl sign = new DS20SignCtlClass();private Certificates certs;public Certificate cur_cert;public SignClass(string strIssuerDn){DS20SignLib.Filter filter = this.sign.Filter;filter.Clear();filter.Issuer = strIssuerDn;this.certs = this.sign.Certificates;}public int GetCertsCount() =>this.certs.Count;public string[] GetCommandNameList(){int count = this.certs.Count;if (count <= 0){return null;}string[] strArray = new string[count];for (int i = 0; i < count; i++){strArray[i] = ((Certificate)this.certs[i]).CommonName;}return strArray;}public Dictionary<string, string> GetCurCertInfo(){if (this.cur_cert == null){throw new Exception("没有指定证书");}return new Dictionary<string, string> {{"CommonName",this.cur_cert.CommonName},{"Subject",this.cur_cert.Subject},{"Issuer",this.cur_cert.Issuer},{"SerialNumber",this.cur_cert.SerialNumber},{"ValidFrom",this.cur_cert.ValidFrom.ToString("yyyy年MM月dd日")},{"ValidTo",this.cur_cert.ValidTo.ToString("yyyy年MM月dd日")}};}public string GetCurCertName(){if (this.cur_cert == null){throw new Exception("没有指定证书");}foreach (string str2 in this.cur_cert.Subject.Split(new char[] { ',' })){string str3 = str2.Substring(0, str2.IndexOf("="));string str4 = str2.Substring(str2.IndexOf("=") + 1);if (((str3.Trim().ToLower() == "ou") && (str4.Trim().ToLower() != "zljca")) && (str4.Trim().ToLower() != "国家知识产权局")){return str4;}}return "";}public bool IsVaild(){if (this.cur_cert == null){throw new Exception("没有指定证书");}return (this.cur_cert.ValidTo >= DateTime.Now);}public bool SetCurrentCert(int index){if (this.certs.Count <= 0){throw new Exception("没有找到证书");}if (this.certs[index] == null){throw new Exception("指定证书越界");}this.cur_cert = (Certificate)this.certs[index];return (this.cur_cert != null);}public bool SetCurrentCert(string commonname){if (this.certs.Count <= 0){throw new Exception("没有找到证书");}for (int i = 0; i < this.certs.Count; i++){Certificate certificate = (Certificate)this.certs[i];if (certificate.CommonName == commonname){this.cur_cert = certificate;break;}}return (this.cur_cert != null);}public string SignFile(string path){if (this.cur_cert == null){throw new Exception("没有指定证书");}return this.cur_cert.EnvSignFile(path, 0);}public SignFileReturnClass SignFile(string path, string sign_exe_path, string IssuerDn){SignFileReturnClass class2;if (this.cur_cert == null){throw new Exception("没有指定证书");}if (!File.Exists(sign_exe_path)){throw new Exception("签名验证程序文件不存在");}string fileName = "\"" + sign_exe_path + "\"";string arguments = "\"" + this.cur_cert.CommonName + "\" \"" + IssuerDn + "\" \"" + path + "\"";ProcessStartInfo startInfo = new ProcessStartInfo(fileName, arguments){RedirectStandardOutput = true,RedirectStandardInput = true,CreateNoWindow = true,UseShellExecute = false};string str3 = "";try{Process process = Process.Start(startInfo);str3 = process.StandardOutput.ReadToEnd();process.WaitForExit();if (string.IsNullOrEmpty(str3.Trim())){throw new Exception("没有获取到返回值");}string returncode = str3.Substring(0, 2);string returnstring = str3.Substring(3);class2 = new SignFileReturnClass(returncode, returnstring);}catch (Exception exception){throw exception;}return class2;}public string SignString(string strChars){if (this.cur_cert == null){throw new Exception("没有指定证书");}return this.cur_cert.Sign(strChars);}public bool VerifyFile(string path, string encryptString) =>(this.sign.VerifyEnvFile(encryptString, 0, path) != null);}namespace Utility{public class SignFileReturnClass{private string returncode;private string returnstring;public SignFileReturnClass(string returncode, string returnstring){this.returncode = returncode;this.returnstring = returnstring;}public string ReturnCode{get =>this.returncode;set =>returncode = value;}public string ReturnString{get =>this.returnstring;set =>returnstring = value;}}}

需要引用CPC目录下的 Ds20Sign.dll 文件,这个不是.net链接库,直接添加引用就好了。

用自己的代码签名看看:

真的签名失败,而这个错误码是 Ds20Sign.dll 里报出来的,没办法,只能认为是证书的问题了,这个签名只是本地签名,似乎没有与CPC服务器通讯,暂且认为是本地证书的问题吧!签名测试我使用了真实的案卷文件,在Temp/Upload/zip目录下,签名成功的话会生成一个签名文件,这是CPC的逻辑,我只是照搬下来!

理论上找http://www.kairende.com/可以解决返回10001的错误原因,从这公司的网站可以看得出来,没有技术支持费用估计人家不会提供文档或是理你!专利局开发CPC那帮人购买了他们的CA产品?

假设你都已经编辑完成了,现在可以签名提交了。

如果证书没有问题,签名通过之后就是打包上传了,上传成功,恭喜你,完成专利申请的递交了,等待受理!

四,想对专利局那帮程序员说点什么~!

1.重写代码,并使用.net 4.6以上版本开发,明年.Net 5都快出来了;

2.别用DevExpress了吧,有花钱买吗?

3.可以多用开源的组件,如NOPI,这样可以不用依赖MS Office,现在电脑我都不安装Office家庭了,用WPS足够能够应付日常工作。

4.网站功能重写,兼容IE\Firefox\Safari\Chrome等。为什么登录总是检测不到证书?为什么IE问题验证码错误?放弃Ds20Sign.dll换个别的方案吧!?证书签名的方案很多的啊!最好是有开源的!

5.招一个月薪超过5000的程序员开发!

6.再招个产品经理,规划一下软件功能!

7.招一个技术总监,将系统重新架构一下!

祝你们好运!别再开发出一堆屎,影响国家形象!

对了,你会问我后来是怎么申请发明专利的。我放弃软件递交了,因为签名错误是一个不可逾越的问题,再加上我也没有办法重新下载证书,还能怎么办!?经过两天熬夜到4点,最后还是打印申请文件,邮递到代办点了!~

我不打算找中介,没钱!

专利在线申请之入门到精通再到放弃相关推荐

  1. 利用VMware虚拟机配置电子专利在线申请系统

    本文教你配置一个在线电子专利申请系统,而且一劳永逸.并且提供了一个完善的系统,放置在百度网盘,下载导入VMware即可使用. 相信很多人在自己申请专利,可以用CPC客户端软件,但是频繁调用word插件 ...

  2. 学银在线python课程_Python 从入门到精通:一个月就够了!

    毫无疑问,Python 是当下最火的编程语言之一.对于许多未曾涉足计算机编程的领域「小白」来说,深入地掌握 Python 看似是一件十分困难的事.其实,只要掌握了科学的学习方法并制定了合理的学习计划, ...

  3. 视频教程-JSP从入门到精通2016+在线视频教学平台项目实训-其他

    JSP从入门到精通2016+在线视频教学平台项目实训 19年软件开发经验,设计开发40多个大型软件,10年从事高等教育,主要为java系列课程,带你轻松进入java生涯. 赖国荣 ¥68.00 立即订 ...

  4. JAVA入门到精通-第94讲-山寨QQ项目8-好友在线提示

    遇到的问题: 现在每登录一个人,后面的人是能看到前面的登录的人的: 但是,前面的人看不到后面的人登录: //后面每登录一个人,有责任去通知前面登录的人他已经上线了: 通知了完以后,需要更改好友在线的情 ...

  5. EFCore 从入门到精通-8(再谈映射关系)

    1.初始准备 开发软件:VisualStudio2022,EFCore6.0 .net Core版本:.Net6.0 数据库:mysql8.0 数据库管理软件:Navicat 按照前面的教程,安装相关 ...

  6. GOOGLE搜索从入门到精通v3.0 from:http://www.being.org.cn/tool/google.htm

    GOOGLE搜索从入门到精通v3.0 原文:http://www.lasg.ac.cn/docs/googlebook.html 作者:donquix 内容 1,前言 2,摘要 3,如何使用本文 4, ...

  7. [推荐]GOOGLE搜索从入门到精通v3.0

    作者:donquix (donquix@sina.com) ------------------------------ 内容 1,前言 2,摘要 3,如何使用本文 4,GOOGLE简介 5,搜索入门 ...

  8. GOOGLE搜索从入门到精通v3.0

    内容 1,前言 2,摘要 3,如何使用本文 4,GOOGLE简介 5,搜索入门 6,初阶搜索 6.1,搜索结果要求包含两个及两个以上关键字 6.2,搜索结果要求不包含某些特定信息 6.3,搜索结果至少 ...

  9. Python 从入门到精通:一个月就够了?真的能行嘛?

    毫无疑问,Python 是当下最火的编程语言之一.对于许多未曾涉足计算机编程的领域「小白」来说,深入地掌握 Python 看似是一件十分困难的事.其实,只要掌握了科学的学习方法并制定了合理的学习计划, ...

最新文章

  1. VS Code配置PHP XDebug
  2. 算法学习(五)---队列
  3. BZOJ3916 [Baltic2014]friends
  4. Windows Server 2008 R2安装Zune 4.0解决方法
  5. nginx反向代理+缓存开启+url重写+负载均衡(带健康探测)的部署记录
  6. 今日头条架构演进之路——高压下的架构演进专题(含PPT)
  7. HDU - 1272小希的迷宫
  8. MyBatis源码阅读指南
  9. PID算法的原理和公式
  10. socket程序退出后端口依然被占用问题的解决
  11. 如何使用google code
  12. Elasticsearch生命周期ILM若干时间后自动删除索引index
  13. 云台山茶旅集团各分子版块日新月(2月20日)
  14. 基于Python改变图片像素大小
  15. 软件测试专业山东大学好考吗,去山大复试跪了,谈谈我的血泪史,以资后来人...
  16. 关于小游戏初步开发的一些理解
  17. Java实例-查找数组中的重复元素
  18. 模拟烟雾传感器 (MQ2)
  19. 关于RouterOS 6.X使用3322域名的脚本
  20. Origin 2018中文版软件下载和安装教程|兼容Win10(上)

热门文章

  1. 渗压计工作原理及基准值确定方法
  2. yandex浏览器_15分钟内制作自己的文本编辑器:Yandex的实践
  3. [OS-Linux]详解Linux的文件系统、inode和动静态库
  4. 创蓝闪验一键登录(Java实现)
  5. 动态域名解析--每步动态域名解析
  6. i致我们终将组件化的Web
  7. php slug,php 中的var
  8. (2021)Top5 免费视频编辑软件,视频剪辑必备工具
  9. Arduino 有源蜂鸣器实验
  10. 例说学习方法的改造和提升