在调用RSA加密的.pfx密钥时,在本地调试没有问题,可以布署到服务器,就会报以下的错误: 用户代码未处理 System.Security.Cryptography.CryptographicException
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<span style="line-height:1.5 !important;"> HResult</span>=-<span style="color:#800080;line-height:1.5 !important;">2146893792</span><span style="line-height:1.5 !important;"> Message</span>=<span style="line-height:1.5 !important;">出现了内部错误。 Source</span>=<span style="line-height:1.5 !important;">mscorlib StackTrace: 在 System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) 在 System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromFile(String fileName, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle</span>&<span style="line-height:1.5 !important;"> pCertCtx) 在 System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromFile(String fileName, Object password, X509KeyStorageFlags keyStorageFlags) 在 System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags) 在 xxxxx.API.Tools.RSA.Sign(String data, String keyPath, String keyPasswd) 在 xxxxx.API.Tools.Encrypt.signANDencrypt(MsgBean req_bean) 在 xxxxx.API.xxxxx.GetBankCardInfo(String orderId, String cardNo) 在 xxxxx.GetBankCardInfo(GetBankCardInfoReq request) 位置 d:\app_service\WHTR_SOA\WHTR.SOA.Services\OnlinePay\Yilian\OnlinePayService.cs:行号 </span><span style="color:#800080;line-height:1.5 !important;">108</span><span style="line-height:1.5 !important;"> 在 Castle.Proxies.Invocations.xxxxx.InvokeMethodOnTarget() 在 Castle.DynamicProxy.AbstractInvocation.Proceed() 在 xxxxx.CastleMethodInvocation.Proceed() 位置 d:\xxxxx.cs:行号 </span><span style="color:#800080;line-height:1.5 !important;">80</span><span style="line-height:1.5 !important;"> 在 xxxxx.Intercept(IMethodInvocation invocation) 位置 d:\xxxxx.cs:行号 </span><span style="color:#800080;line-height:1.5 !important;">56</span><span style="line-height:1.5 !important;"> InnerException: </span> |
处理方法: IIS 应用程序池--选中你网站的所配置的应用程序池--右键 选择 “高级配置” --将“加载用户配置文件” 设置为True 。问题解决 from:http://www.cnblogs.com/jys509/p/4499978.html
View Details
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
//------------------------------------------------------------------------------ // <copyright file="CryptoUtil.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ namespace System.Web.Security.Cryptography { using System; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using System.Web.Util; // Contains helper methods for dealing with cryptographic operations. internal static class CryptoUtil { /// <summary> /// Similar to Encoding.UTF8, but throws on invalid bytes. Useful for security routines where we need /// strong guarantees that we're always producing valid UTF8 streams. /// </summary> public static readonly UTF8Encoding SecureUTF8Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); /// <summary> /// Converts a byte array into its hexadecimal representation. /// </summary> /// <param name="data">The binary byte array.</param> /// <returns>The hexadecimal (uppercase) equivalent of the byte array.</returns> public static string BinaryToHex(byte[] data) { if (data == null) { return null; } char[] hex = new char[checked(data.Length * 2)]; for (int i = 0; i < data.Length; i++) { byte thisByte = data[i]; hex[2 * i] = NibbleToHex((byte)(thisByte >> 4)); // high nibble hex[2 * i + 1] = NibbleToHex((byte)(thisByte & 0xf)); // low nibble } return new string(hex); } // Determines if two buffer instances are equal, e.g. whether they contain the same payload. This method // is written in such a manner that it should take the same amount of time to execute regardless of // whether the result is success or failure. The modulus operation is intended to make the check take the // same amount of time, even if the buffers are of different lengths. // // !! DO NOT CHANGE THIS METHOD WITHOUT SECURITY [MethodImpl(MethodImplOptions.NoOptimization)] public static bool BuffersAreEqual(byte[] buffer1, int buffer1Offset, int buffer1Count, byte[] buffer2, int buffer2Offset, int buffer2Count) { Debug.ValidateArrayBounds(buffer1, buffer1Offset, buffer1Count); Debug.ValidateArrayBounds(buffer2, buffer2Offset, buffer2Count); bool success = (buffer1Count == buffer2Count); // can't possibly be successful if the buffers are of different lengths for (int i = 0; i < buffer1Count; i++) { success &= (buffer1[buffer1Offset + i] == buffer2[buffer2Offset + (i % buffer2Count)]); } return success; } /// <summary> /// Computes the SHA256 hash of a given input. /// </summary> /// <param name="input">The input over which to compute the hash.</param> /// <returns>The binary hash (32 bytes) of the input.</returns> public static byte[] ComputeSHA256Hash(byte[] input) { return ComputeSHA256Hash(input, 0, input.Length); } /// <summary> /// Computes the SHA256 hash of a given segment in a buffer. /// </summary> /// <param name="buffer">The buffer over which to compute the hash.</param> /// <param name="offset">The offset at which to begin computing the hash.</param> /// <param name="count">The number of bytes in the buffer to include in the hash.</param> /// <returns>The binary hash (32 bytes) of the buffer segment.</returns> public static byte[] ComputeSHA256Hash(byte[] buffer, int offset, int count) { Debug.ValidateArrayBounds(buffer, offset, count); using (SHA256 sha256 = CryptoAlgorithms.CreateSHA256()) { return sha256.ComputeHash(buffer, offset, count); } } /// <summary> /// Returns an IV that's based solely on the contents of a buffer; useful for generating /// predictable IVs for ciphertexts that need to be cached. The output value is only /// appropriate for use as an IV and must not be used for any other purpose. /// </summary> /// <remarks>This method uses an iterated unkeyed SHA256 to calculate the IV.</remarks> /// <param name="buffer">The input buffer over which to calculate the IV.</param> /// <param name="ivBitLength">The requested length (in bits) of the IV to generate.</param> /// <returns>The calculated IV.</returns> public static byte[] CreatePredictableIV(byte[] buffer, int ivBitLength) { // Algorithm: // T_0 = SHA256(buffer) // T_n = SHA256(T_{n-1}) // output = T_0 || T_1 || ... || T_n (as many blocks as necessary to reach ivBitLength) byte[] output = new byte[ivBitLength / 8]; int bytesCopied = 0; int bytesRemaining = output.Length; using (SHA256 sha256 = CryptoAlgorithms.CreateSHA256()) { while (bytesRemaining > 0) { byte[] hashed = sha256.ComputeHash(buffer); int bytesToCopy = Math.Min(bytesRemaining, hashed.Length); Buffer.BlockCopy(hashed, 0, output, bytesCopied, bytesToCopy); bytesCopied += bytesToCopy; bytesRemaining -= bytesToCopy; buffer = hashed; // next iteration (if it occurs) will operate over the block just hashed } } return output; } /// <summary> /// Converts a hexadecimal string into its binary representation. /// </summary> /// <param name="data">The hex string.</param> /// <returns>The byte array corresponding to the contents of the hex string, /// or null if the input string is not a valid hex string.</returns> public static byte[] HexToBinary(string data) { if (data == null || data.Length % 2 != 0) { // input string length is not evenly divisible by 2 return null; } byte[] binary = new byte[data.Length / 2]; for (int i = 0; i < binary.Length; i++) { int highNibble = HttpEncoderUtility.HexToInt(data[2 * i]); int lowNibble = HttpEncoderUtility.HexToInt(data[2 * i + 1]); if (highNibble == -1 || lowNibble == -1) { return null; // bad hex data } binary[i] = (byte)((highNibble << 4) | lowNibble); } return binary; } // converts a nibble (4 bits) to its uppercase hexadecimal character representation [0-9, A-F] private static char NibbleToHex(byte nibble) { return (char)((nibble < 10) ? (nibble + '0') : (nibble - 10 + 'A')); } } } |
我在开发测试过程中,发现使用wx.onMenuShareTimeline无效果,没有显示我定义的图片、title和链接,经过调试发现原因如下: 1.图片大小要大于300pix才能显示 2.这个方法必须先config成功,然后再wx.ready里才能调用。我直接放到$(function(){})里执行,实践证明是不行的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '{$appid}', // 必填,公众号的唯一标识 timestamp: "{$signPackage.timestamp}", // 必填,生成签名的时间戳 nonceStr: '{$signPackage.nonceStr}', // 必填,生成签名的随机串 signature: '{$signPackage.signature}',// 必填,签名,见附录1 jsApiList: ['checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function () { wx.onMenuShareTimeline({ title: '--{$info.name}', // 分享标题 link: '{$url}__URL__/index?pid={$pid}&puid={$uid}', // 分享链接,将当前登录用户转为puid,以便于发展下线 imgUrl: '{$url}__PUBLIC__/Uploads/{$goodsvo.image}', // 分享图标 success: function () { // 用户确认分享后执行的回调函数 alert('分享成功'); }, cancel: function () { // 用户取消分享后执行的回调函数 } }); wx.error(function (res) { // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 alert("errorMSG:" + res); }); }); |
from:http://www.cnblogs.com/zhouyu629/p/4496065.html
View DetailsWIN2003的服务器,打开系统自带的防火墙后,用FLASHFXP连接FTP时出现沟通困难,无法列表数据,FTP无法连接,通过检查后发现WIN2003在默认情况下,该防火墙是禁止开放本机FTP服务的。通过一系列的试验发现解决该问题的方法,希望对大家有所帮助,步骤如下所述: 第1步,点击开始菜单,进入控制面板,选择WINDOW防火墙,进入防火墙设置窗口,选择例外菜单,进入防火墙例外窗口,之后点击下方的添加端口,出现添加端口对话框,在此设置名称FTP,和开启端口21后,点击确定,如图1所示: 图1防火墙例外中添加端口设置 第2步,在桌面上右键单击“网上邻居”图标,选择“属性”命令。在打开的“网络连接”窗口中右键单击“本地连接”图标,选择“属性”命令,之后选择高级按钮,点击设置进入WINDOW防火墙设置窗口,如图2所示: 图2本地连接属性进入防火墙设置 第3步,打开“防火墙设置”对话框,切换到“高级”选项卡。单击本地连接对话框右侧的“设置”按钮,打开“高级设置”对话框。 图3本地连接高级设置窗口 第4步,在默认的“服务”选项卡中,用户可以设置在开启防火墙功能的前提下本机开放的服务类别。由于需要提供FTP服务,因此只需开放该服务即可。在服务列表中选中“FTP服务器”选项,随之打开的“服务设置”对话框要求填写计算机名称。保持默认内容并连续单击“确定”完成设置即可,如图4所示。 from:http://blog.pynet.net/u/pyxyp/archives/2011/99.html
View DetailsNavigator 对象 Navigator 对象包含有关浏览器的信息。 注释:没有应用于 navigator 对象的公开标准,不过所有浏览器都支持该对象。 Navigator 对象集合 集合 描述 plugins[] 返回对文档中所有嵌入式对象的引用。 该集合是一个 Plugin 对象的数组,其中的元素代表浏览器已经安装的插件。Plug-in 对象提供的是有关插件的信息,其中包括它所支持的 MIME 类型的列表。 虽然 plugins[] 数组是由 IE 4 定义的,但是在 IE 4 中它却总是空的,因为 IE 4 不支持插件和 Plugin 对象。 Navigator 对象属性 属性 描述 appCodeName 返回浏览器的代码名。 appMinorVersion 返回浏览器的次级版本。 appName 返回浏览器的名称。 appVersion 返回浏览器的平台和版本信息。 browserLanguage 返回当前浏览器的语言。 cookieEnabled 返回指明浏览器中是否启用 cookie 的布尔值。 cpuClass 返回浏览器系统的 CPU 等级。 onLine 返回指明系统是否处于脱机模式的布尔值。 platform 返回运行浏览器的操作系统平台。 systemLanguage 返回 OS 使用的默认语言。 userAgent 返回由客户机发送服务器的 user-agent 头部的值。 userLanguage 返回 OS 的自然语言设置。 Navigator 对象方法 方法 描述 javaEnabled() 规定浏览器是否启用 Java。 taintEnabled() 规定浏览器是否启用数据污点 (data tainting)。 from:http://www.w3school.com.cn/jsref/dom_obj_navigator.asp
View DetailsWebStorage是HTML5中本地存储的解决方案之一,在HTML5的WebStorage概念引入之前除去IE User Data、Flash Cookie、Google Gears等看名字就不靠谱的解决方案,浏览器兼容的本地存储方案只有使用cookie。有同学可能会问,既然有了cookie本地存储,为什么还要引入WebStorage的概念? Cookie肿么了 cookie的缺陷是非常明显的 1. 数据大小:作为存储容器,cookie的大小限制在4KB左右这是非常坑爹的,尤其对于现在复杂的业务逻辑需求,4KB的容量除了存储一些配置字段还简单单值信息,对于绝大部分开发者来说真的不知指望什么了。 2. 安全性问题:由于在HTTP请求中的cookie是明文传递的(HTTPS不是),带来的安全性问题还是很大的。 3. 网络负担:我们知道cookie会被附加在每个HTTP请求中,在HttpRequest 和HttpResponse的header中都是要被传输的,所以无形中增加了一些不必要的流量损失。 WebStorage WebStorage是HTML新增的本地存储解决方案之一,但并不是为了取代cookie而制定的标准,cookie作为HTTP协议的一部分用来处理客户端和服务器通信是不可或缺的,session正是依赖于实现的客户端状态保持。WebStorage的意图在于解决本来不应该cookie做,却不得不用cookie的本地存储。 WebStorage提供两种类型的API:localStorage和sessionStorage,两者的区别看名字就有大概了解,localStorage在本地永久性存储数据,除非显式将其删除或清空,sessionStorage存储的数据只在会话期间有效,关闭浏览器则自动删除。两个对象都有共同的API。 复制代码 代码如下: interface Storage { readonly attribute unsigned long length; DOMString? key(unsigned long index); getter DOMString getItem(DOMString key); setter creator void setItem(DOMString key, DOMString value); deleter void removeItem(DOMString key); void clear(); }; 1、length:唯一的属性,只读,用来获取storage内的键值对数量。 2、key:根据index获取storage的键名 3、getItem:根据key获取storage内的对应value 4、setItem:为storage内添加键值对 5、removeItem:根据键名,删除键值对 6、clear:清空storage对象 WebStorage如何使用 在实现了WebStorage的浏览器中,页面有两个全局的对象localStorage和sessionStorage 以localStorage为例,看一段简单的操作代码 复制代码 代码如下: var ls=localStorage; console.log(ls.length);//0 ls.setItem('name',’Byron'); ls.setItem('age',’24'); console.log(ls.length);//2 //遍历localStorage for(var i=0;i<ls.length;i++){ /* age : 24 […]
View Details
1 2 3 4 5 6 7 8 9 10 11 12 13 |
if(/AppleWebKit.*mobile/i.test(navigator.userAgent) || (/MIDP|SymbianOS|NOKIA|SAMSUNG|LG|NEC|TCL|Alcatel|BIRD|DBTEL|Dopod|PHILIPS|HAIER|LENOVO|MOT-|Nokia|SonyEricsson|SIE-|Amoi|ZTE/.test(navigator.userAgent))){ if(window.location.href.indexOf("?mobile")<0){ try{ if(/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)){ window.location.href="手机页面"; }else if(/iPad/i.test(navigator.userAgent)){ window.location.href="平板页面"; }else{ window.location.href="其他移动端页面" } }catch(e){} } } |
另外的三种: 版本1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<script language="javascript"> //平台、设备和操作系统 var system ={ win : false, mac : false, xll : false }; //检测平台 var p = navigator.platform; system.win = p.indexOf("Win") == 0; system.mac = p.indexOf("Mac") == 0; system.x11 = (p == "X11") || (p.indexOf("Linux") == 0); //跳转语句,如果是手机访问就自动跳转到caibaojian.com页面 if(system.win||system.mac||system.xll){ }else{ window.location.href="http://caibaojian.com"; } </script> |
版本2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<script language="javascript"> function is_mobile() { var regex_match = /(nokia|iphone|android|motorola|^mot-|softbank|foma|docomo|kddi|up.browser|up.link|htc|dopod|blazer|netfront|helio|hosin|huawei|novarra|CoolPad|webos|techfaith|palmsource|blackberry|alcatel|amoi|ktouch|nexian|samsung|^sam-|s[cg]h|^lge|ericsson|philips|sagem|wellcom|bunjalloo|maui|symbian|smartphone|midp|wap|phone|windows ce|iemobile|^spice|^bird|^zte-|longcos|pantech|gionee|^sie-|portalmmm|jigs browser|hiptop|^benq|haier|^lct|operas*mobi|opera*mini|320x320|240x320|176x220)/i; var u = navigator.userAgent; if (null == u) { return true; } var result = regex_match.exec(u); if (null == result) { return false } else { return true } } if (is_mobile()) { document.location.href= 'http://caibaojian.com'; //修改http://caibaojian.com为你所需跳转目标页地址 } </script> |
版本3 百度webapp版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<!---识别手机或电脑的js开始---> <script language="javascript"> (function(){ var res = GetRequest(); var par = res['index']; if(par!='gfan'){ var ua=navigator.userAgent.toLowerCase(); var contains=function (a, b){ if(a.indexOf(b)!=-1){return true;} }; //将下面的http://caibaojian.com改成你的wap手机版页面地址 如我的 http://caibaojian.com var toMobileVertion = function(){ window.location.href = 'http://caibaojian.com/' } if(contains(ua,"ipad")||(contains(ua,"rv:1.2.3.4"))||(contains(ua,"0.0.0.0"))||(contains(ua,"8.0.552.237"))){return false} if((contains(ua,"android") && contains(ua,"mobile"))||(contains(ua,"android") && contains(ua,"mozilla")) ||(contains(ua,"android") && contains(ua,"opera")) ||contains(ua,"ucweb7")||contains(ua,"iphone")){toMobileVertion();} } })(); function GetRequest() { var url = location.search; //获取url中"?"符后的字串 var theRequest = new Object(); if (url.indexOf("?") != -1) { var str = url.substr(1); strs = str.split("&"); for(var i = 0; i < strs.length; i ++) { theRequest[strs[i].split("=")[0]]=unescape(strs[i].split("=")[1]); } } return theRequest; } </script> <!---识别手机或电脑的js结束---> |
Toonz公司开发的软件你可能从未听说过,但是你已经看到过无数的电视节目和电影使用其产品。Toonz公司的主要产品是企业动画软件,集成绘图,编辑,动画和合成等功能。Toonz开发的动画软件,曾经被用于创建《飞出个未来》、《幽灵公主》和《千与千寻》等动画片。 据报道,该动画软件免费开源之前的售价曾经高达每张许可证1万美元。但作为DWANGO收购该公司协议的一部分,Toonz公司宣布其下动画软件免费开源。 吉卜力工作室成像执行总监奥井淳表示,该公司使用Toonz动画软件,因为它可以将手工绘制动画和数字绘制无缝结合。吉卜力工作室首先在1995年使用这款软件制作《幽灵公主》动画片。 3月26日,该公司将发布TOONZ吉卜力工作室版动画软件,其中包括与吉卜力工作室合作开发的功能,让独立动画师无需支付高昂的前期费用就使用该软件。相反,TOONZ公司计划让软件免费,通过出售安装服务,培训和支持来获得利润。 稿源:cnbeta
View Details通过openssl工具生成RSA的公钥和私钥(opnssl工具可在互联网中下载到,也可以点此下载无线接口包,里面包含此工具) 打开openssl文件夹下的bin文件夹,执行openssl.exe文件: 1)生成RSA私钥 输入“生成命令.txt”文件中:“genrsa -out rsa_private_key.pem 1024”,并回车得到生成成功的结果,如下图: 此时,我们可以在bin文件夹中看到一个文件名为rsa_private_key.pem的文件,用记事本方式打开它,可以看到—--BEGIN RSA PRIVATE KEY—--开头,—--END RSA PRIVATE KEY—--结尾的没有换行的字符串,这个就是原始的私钥。 2)把RSA私钥转换成PKCS8格式 输入命令:pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt,并回车当前界面中会直接显示出生成结果,这个结果就是PKCS8格式的私钥,如下图: 右键点击openssl窗口上边边缘,选择编辑→标记,选中要复制的文字(如上图), 此时继续右键点击openssl窗口上边边缘,选择编辑→复制, 把复制的内容粘土进一个新的记事本中,可随便命名,只要知道这个是PKCS8格式的私钥即可。 3)生成RSA公钥 输入命令:rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem,并回车,得到生成成功的结果,如下图: 此时,我们可以在bin文件夹中看到一个文件名为rsa_public_key.pem的文件,用记事本方式打开它,可以看到—--BEGIN PUBLIC KEY—--开头,—--END PUBLIC KEY—--结尾的没有换行的字符串,这个就是公钥。 详情见开放平台对于密钥生成说明 注意:请妥善保管好生成的公私钥! 附:点此查看如何上传公钥 from:https://cshall.alipay.com/enterprise/help_detail.htm?help_id=474010
View DetailsPhotoshop中除了.csh文件之外,还有几种常见的格式文件,比如.abr是画笔文件,.aco是色板文件,.grd是渐变文件,.asl是样式文件,.pat是图案文件,.shc是等高线文件,.csh是自定形状文件,.tpl是工具预设文件。 这些格式文件在电脑中不能和软件、图片这些直接打开使用,通常需要加载之后才能使用。 本文介绍的方法,既是对“csh文件用什么打开,csh是什么格式文件”的回答,做到举一反三,遇到类似的,在网上下载的.abr之类的笔刷如何安装如何使用这些问题,一样可以通过预设管理器中载入之后使用。 本文就来一起学习解决.csh文件用什么打开?具体操作如下: 1.笔者现在使用的Photoshop CS6版本,执行“编辑——预设——预设管理器”,打开“预设管理器”对话框。 2.在“预设类型”下拉框中选择“自定形状”,单击“载入”。 说明:比如我们需要安装在网上下载的画笔笔刷,此时在“预设类型”中选择“画笔”,单击“载入”即可。其余格式文件安装方法一样。 3.弹出“载入”对话框,选择相应的.csh文件,单击“载入”即可。 4.单击“完成”,关闭“预设管理器”对话框。 5.在工具箱中找到“自定形状工具”,在自定形状工具属性栏中,单击“形状”下拉箭头,可以找到我们上面载入的.csh文件。 from:http://www.ittribalwo.com/article/2161.html
View Details