1月 31

PrimoCache就是FancyCache的更新版本,新安装有90天试用期,到期清理注册表后重装又是90天,可如此反复90天;此外,官网论坛也会不断发布试用key激活授权文件。   

  

PrimoCache是一个可以将系统内存或闪存虚拟成硬盘缓存的软件。它把从硬盘中读取的数据存入系统内存或闪存,使系统在下次访问该数据时可以很快从内存读取,避免再次读取速度较慢的硬盘,从而突破硬盘瓶颈,提升系统性能。 

 

PrimoCache还具有检测和利用系统未识别内存的功能,解决32位Windows操作系统无法完全使用4G或更多内存的问题。通过将检测到的系统未识别内存用作硬盘缓存的方式,PrimoCache使计算机可以利用全部安装的内存。 基本原理 PrimoCache为硬盘分配内存作缓存,并拦截系统发送至硬盘的IO请求。如果IO请求读取的数据已经在缓存中,则直接读取缓存中的数据并完成IO请求。否则数据则从硬盘中读取出来,并存入缓存,同时完成IO请求。由此可见,从缓存读取的数据量越多,则系统性能提升的越多。

 

已经使用PrimoCache很久了,之前是用的2.0版本的,但是每次到期就要重新安装一下系统,比较麻烦.有过购买正版的想法,不过看了价格还是打消了念头,至少证明这款软件确实很好用.

 

发现有1.0.1版本的破解方法,果断使用了.记录一下破解方法

 

安装primocache(用90试用key,官网有下)使用直到或快到期后:

1、安装(压缩包内)包含的RegistrarHomeV4 软件(放心,是正规的注册表管理软件,网上可搜到,就用压缩包里的32版本就行)

2、运行(RegistrarHomeV4),点“”Home Edition(家庭版 )“”

3、按Ctrl+F 打开搜索工具

4、搜索 a257d54e-6769-4397-b2d2-9f75024b3156

5、右键搜索到的条目并且点删除

6、搜索 22DDE72D-542C-454b-845F-6D4579DDEED1

7、右键搜索到的条目并且点删除

8、重启系统

9、这样就重置了90天的试用。当90天再次试用完后,只需重复以上步骤即可一直90试用了。

另外,用系统自带注册表工具删除以上键值是没法重置的,老实按上边步骤就好

written by ocean \\ tags:

1月 26

找了一份不错的源码,学习一下验证码识别

第一步当然是批量下载验证码了

        static void Main(string[] args)
        { 
            string downloadPath = Path.Combine(Config.Root, @"yzm\58"); 
            for (int index = 0; index < 200; index++)
            { 
                Random r = new Random(); 
                string url = "https://passport.58.com/validatecode?temp=123ijv4f6wg&t=" + r.Next(1, 9999);
                SaveCodeImageFromUrl(url, downloadPath + "\\" + index + ".jpg"); 
            }
        }


        public static void SaveCodeImageFromUrl(string url, string path)
        {

            WebRequest re = WebRequest.Create(url);
            WebResponse rp = re.GetResponse();
            Stream s = rp.GetResponseStream();
            Image img = Image.FromStream(s);
            s.Close();
            s.Dispose();
            img.Save(path);
        }

第二步,灰度处理

        static void Main(string[] args)
        { 
            string downloadPath = Path.Combine(Config.Root, @"yzm\58\");

            var files=Directory.GetFiles(downloadPath+"old");
            foreach (var file in files)
            {
                Image img = Image.FromFile(file);
                Image img_grey = (Image)img.Clone();

                string imgOriginal = Image2Num((Bitmap)img_grey);


                if (!Directory.Exists("experiment\\"))
                {
                    Directory.CreateDirectory("experiment\\");
                }
                //imgurl = pborigin.ImageLocation;
                WriteToFile(imgOriginal, "experiment\\" + Path.GetFileNameWithoutExtension(file) + "_original.txt");
                 
                img_grey = ImageProcess.Gray((Bitmap)img_grey, 2);
                string imgGreied = Image2Num((Bitmap)img_grey);
                WriteToFile(imgGreied, "experiment\\" + Path.GetFileNameWithoutExtension(file) + "_greied.txt");

                img_grey.Save(Path.Combine(Config.Root, @"yzm\58\huidu\") + Path.GetFileName(file));

            }
             


        }

        /// <summary>
        /// 将数据写入文件
        /// </summary>
        /// <param name="data"></param>
        /// <param name="path"></param>
        public static void WriteToFile(string data, string path)
        {
            File.WriteAllText(path, data);
        }

        /// <summary>
        /// 图片转换成像素数值
        /// </summary>
        /// <param name="img"></param>
        /// <returns></returns>
        #region 图片转换成像素数值
        public static string Image2Num(Bitmap img)
        {

            StringBuilder sb = new StringBuilder();
            string imgPixel = "";
            int height = img.Height;
            int width = img.Width;
            BitmapData bdata = img.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            int bytelength = width * height * 4;
            byte[] bytes = new byte[bytelength];
            Marshal.Copy(bdata.Scan0, bytes, 0, bytelength);
            int row = 1;
            for (int i = 0; i < bytelength; i += 4)
            {
                imgPixel = bytes[i] + "," + bytes[i + 1] + "," + bytes[i + 2];
                if (imgPixel.Length < 11)
                {
                    for (int j = 0; j < 11 - imgPixel.Length; j++)
                    {
                        imgPixel += " ";
                    }
                }
                imgPixel += "\t";
                sb.Append(imgPixel);
                if (row % width == 0)
                {
                    sb.Append("\r\n");
                }
                row++;
            }
            img.UnlockBits(bdata);
            return sb.ToString();
        }
        #endregion

written by ocean

1月 20

开发了个新网站,里面会存在一些表里需要统计记录点击数,然后按照点击数出一个热门列表的功能.

 

然后就渐渐发现这个是一个很常见的功能,很多表都有这个需求,一般做法都是在每个表中加Hit字段,然后order by hit 取列表,这也没什么,关键是我这个小站点,后台在本机,没在线上,所以如果更新数据的话,大多数情况就是覆盖更新,然后就会出现一个问题就是这些表里的点击数量又没了,因为被覆盖了.

当然也不是解决不了,就是不要覆盖更新,写个程序慢慢更新,或者写个sql自己定义更新的列.不过我比较懒,还是嫌麻烦,身为程序员,我懒我自豪

所以就有了这个插件形式存在的表,所有的点击数都记录在这个表里,更新的时候不覆盖这个表就好了,耶

表定义

CREATE TABLE `sys_hit` (
`TableName`  varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' ,
`Key1`  varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' ,
`Key2`  varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' ,
`Key3`  varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL  DEFAULT '' ,
`Count`  int(11) NOT NULL DEFAULT 0 ,
PRIMARY KEY (`TableName`, `Key1`, `Key2`, `Key3`)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
ROW_FORMAT=COMPACT
;

tablename就是要添加hit的表的名称, key1,key2,key3是指该表的主键,

如果但主键就只用Key1,双主键就Key1,Key2,三主键就Key1,Key2,Key3,四主键嘛就再加字段喽

一般三个就够了,一般哦

 

数据实体

    public class HitInfo
    {
        public string TableName { get; set; }
        public int Domain { get; set; }
        public string Key { get; set; }
        public int Count { get; set; }
    }

数据访问类

public class HitDAL
    { 
        /// <summary>
        /// 点击埋点
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="domain"></param>
        /// <param name="key"></param>
        public static void Hit(string tableName, object key1, object key2,object key3)
        {
            try
            {
                var isUpdate = UpdateHit(tableName, key1,key2,key3);
                if (!isUpdate)
                {
                    Insert(tableName, key1, key2, key3);
                }
            }
            catch (Exception ex) //Catch掉,因为不能影响主进程
            {
                LogHelper.Info("点击量更新错误" + ex.Message);
            }
        }

        private static bool UpdateHit(string tableName, object key1, object key2, object key3)
        { 
            using (IDbConnection connection = new MySqlConnection(Config.ConnectionString))
            {
                var result = connection.Execute(@"UPDATE sys_hit SET `Count`=`Count`+1 WHERE TableName=?TableName AND Key1=?Key1 AND `Key2`=?Key2 AND `Key3`=?Key3 ", new { TableName = tableName, Key1 = key1, Key2 = key2, Key3 = key3 });
                return result > 0;
            }
        }

        private static bool Insert(string tableName, object key1, object key2, object key3)
        {
            using (IDbConnection connection = new MySqlConnection(Config.ConnectionString))
            {
                var result = connection.Execute(@"insert sys_hit(TableName,Key1,`Key2`,Key3,`Count`)values(?TableName,?Key1,?Key2,?Key3,?Count)", new { TableName = tableName,  Key1 = key1, Key2 = key2, Key3 = key3, Count = 1 });
                return result > 0;
            }
        }
 
    }

数据访问还是用的Dapper+Mysql的形式

现在是调用埋点,双主键

            //更新点击数量
            if (model.Book != null) HitDAL.Hit("tb_book", ((int)this.Domain), id.ToString(), string.Empty);

三主键

            //更新点击数量
            if (model.TVDetail != null) HitDAL.Hit("tb_tvdetail", ((int)this.Domain), tvcode, id);

 

接下来是最关键的取数据了

        /// <summary>
        /// 获取点击榜前10
        /// </summary>
        /// <param name="count"></param>
        /// <param name="domain"></param>
        /// <returns></returns>
      public static List<BookInfo> GetHotBookInfos(int pageSize, EnumDomain domain)
      {
          using (IDbConnection connection = new MySqlConnection(Config.ConnectionString))
          {
              var info = connection.Query<BookInfo>(@"select Id,Title,`Count` from tb_book INNER JOIN sys_hit ON tb_book.id =sys_hit.Key2
                                                     where  domain=?Domain order by `Count` desc limit ?PageSize",
                  new { PageSize = pageSize, Domain = (int)domain }).ToList();
              return info;
          }
      }

在此发现Mysql一个很有意思的性质,条件字段类型不一样也没有问题,好赞!!!

OK,记录到此结束

虽然性能肯定会有所降低,但是就以我的数据量来说,真心没觉得有啥慢的,带来的方便确实是大大的,而且是通用的,噢耶!!!

written by ocean

1月 17

帮助另外一个team改一个bug,主要是涉及到报表的,然后遇到几个坑,填平了记录一下.

首先这个项目报表使用的事SSRS,之前没有做过相关部署,好在资料很多.

 

报表安装配置

需要用到Reporting Services Configuration Manager

Web Service URL 选项卡下有一个 Report Server Web Service URLS, 这个复制下来,就是等会需要发布用到的地址

Database选项卡下配置report数据库

Report Manager URL 下面 就是后台管理的地址,这个等会也会用到

发布部署

在VS中,选择开发好的report project,右键属性页面  

TargetReportFolder  顾名思义,发布上去的文件夹名称

TargetServerURL    复制之前配置用到的 Web Service URL 选项卡下的路径即可

然后右键项目Deploy,即可看到发布进行中,等待完成即可.

 

数据源管理

使用Report Manager URL 下面的URL地址

在浏览器中直接打开

进入Data Sources,配置数据源

最好是记住密码,否则会需要每次输入密码.

安全性里面是报表的用户组的权限的管理,大致就OK了

 

最后记录一点配置日志的东西

日志本身的路径

C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\LogFiles

这里可以管理日志的记录,配置文件如下

C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\ReportServer\bin\ReportingServicesService.exe.config

修改其中的

 <add name="DefaultTraceSwitch" value="4" />

value值从0到4,默认为3,以此希望输出详细的信息

具体值对应见下表

Setting

Description

RStrace

Specifies namespaces used for errors and tracing.

DefaultTraceSwitch

Specifies the level of information that is reported to the ReportServerService trace log. Each level includes the information reported by all lower-numbered levels. Disabling tracing is not recommended. Valid values include:

0= Disables tracing

1= Exceptions and restarts

2= Exceptions, restarts, warnings

3= Exceptions, restarts, warnings, status messages (default)

4= Verbose mode

FileName

Specifies the first portion of the log file name. The value specified by Prefix completes the rest of the name. By default, the name is ReportServerService_.

FileSizeLimitMb

Specifies an upper limit on trace log size. The file is measured in megabytes. Valid values are 0 to a maximum integer. The default value is 32.

KeepFilesForDays

Specifies the number of days after which a trace log file will be deleted. Valid values are 0 to a maximum integer. The default value is 14.

Prefix

Specifies a generated value that distinguishes one log instance from another. By default, timestamp values are appended to trace log file names. This value is set to " tid, time ". Do not modify this setting.

TraceListeners

Specifies a target for outputting trace log content. You can specify multiple targets using a comma to separate each one. Valid values include:

DebugWindow (default)

File (default)

StdOut

TraceFileMode

Specifies whether trace logs contain data for a 24-hour period. You should have one unique trace log for each component on each day. This value is set to "Unique (default)". Do not modify this value.

Components

Specifies the components for which trace logs are created. The default value is all. Other valid values for this setting include the names of internal components. Do not modify this value.

Runtime

Specifies configuration settings that support backward compatibility with the previous version. Runtime settings are used to redirect requests that target the previous version of Microsoft.ReportingServices.Interfaces to the new version.

All of the configuration settings in this section are described in the .NET Framework product documentation. For more information, search for "Runtime Schema Settings" on the MSDN Web site or in the .NET Framework documentation.

 

 

 

 实际开发中,遇到过的问题

对于服务器管理员组的用户,创建及浏览报表文件没有问题,但对于一般用户在查看报表时会提示:“为用户domainname\username授予的权限不足,无法执行此操作。 (rsAccessDenied)”。(The permissions granted to user 'Domain\user' are insufficient for performing this operation. (rsAccessDenied))

 

 解决方法

Start Internet Explorer using "Run as Administrator"

Open http://localhost/reports

Go to properties tab (SSRS 2008)

Security->New Role Assignment

Add DOMAIN/USERNAME or DOMAIN/USERGROUP

Check Report builder

written by ocean \\ tags:

1月 13

加载网址

            webBrowser1.Navigate("http://blog.wx6.org");

根据id找到按钮,然后点击

            HtmlElement tab = webBrowser1.Document.GetElementById("mobileRegTab").FirstChild;
            tab.InvokeMember("Click");

查找元素,获取值,设置值

        //根据Name获取元素
        public HtmlElement GetElement_Name(WebBrowser wb, string Name)
        {
            HtmlElement e = wb.Document.All[Name];
            return e;
        }

        //根据Id获取元素
        public HtmlElement GetElement_Id(WebBrowser wb, string id)
        {
            HtmlElement e = wb.Document.GetElementById(id);
            return e;
        }

        //根据Index获取元素
        public HtmlElement GetElement_Index(WebBrowser wb, int index)
        {
            HtmlElement e = wb.Document.All[index];
            return e;
        }

        //获取form表单名name,返回表单
        public HtmlElement GetElement_Form(WebBrowser wb, string form_name)
        {
            HtmlElement e = wb.Document.Forms[form_name];
            return e;
        }

        //设置元素value属性的值
        public void Write_value(HtmlElement e, string value)
        {
            e.SetAttribute("value", value);
        }

        //执行元素的方法,如:click,submit(需Form表单名)等
        public void Btn_click(HtmlElement e, string s)
        { 
            e.InvokeMember(s);
        }

written by ocean \\ tags: ,

1月 03

研究一下DES对称加密的算法

C#实现如下

    public class DESEncryptHelper
    {

        /// <summary>
        /// DES对称加密的Key
        /// 固定8位
        /// </summary>
        private static string Key = "duRdp3kJ";

        //// <summary> 
        /// DES加密 
        /// </summary> 
        /// <param name="encryptString"></param> 
        /// <returns></returns> 
        public static string DesEncrypt(string encryptString)
        {
            byte[] keyBytes = Encoding.UTF8.GetBytes(Key.Substring(0, 8));
            byte[] keyIV = keyBytes;
            byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            MemoryStream mStream = new MemoryStream();
            CryptoStream cStream = new CryptoStream(mStream, provider.CreateEncryptor(keyBytes, keyIV), CryptoStreamMode.Write);
            cStream.Write(inputByteArray, 0, inputByteArray.Length);
            cStream.FlushFinalBlock();
            return Convert.ToBase64String(mStream.ToArray());
        }

        /// <summary> 
        /// DES解密 
        /// </summary> 
        /// <param name="decryptString"></param> 
        /// <returns></returns> 
        public static string DesDecrypt(string decryptString)
        {
            byte[] keyBytes = Encoding.UTF8.GetBytes(Key.Substring(0, 8));
            byte[] keyIV = keyBytes;
            byte[] inputByteArray = Convert.FromBase64String(decryptString);
            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            MemoryStream mStream = new MemoryStream();
            CryptoStream cStream = new CryptoStream(mStream, provider.CreateDecryptor(keyBytes, keyIV), CryptoStreamMode.Write);
            cStream.Write(inputByteArray, 0, inputByteArray.Length);
            cStream.FlushFinalBlock();
            return Encoding.UTF8.GetString(mStream.ToArray());
        }
    }

 

       [DllImport("Lib.dll", EntryPoint = "DES_Encrypt",  CallingConvention = CallingConvention.Cdecl)]
        public extern static void DES_Encrypt(StringBuilder sz_encrypt);

        [DllImport("Lib.dll", EntryPoint = "DES_Decrypt", CallingConvention = CallingConvention.Cdecl)]
        public extern static void DES_Decrypt(StringBuilder sz_encrypt);
// Lib.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "Lib.h"

#include "des.h"
#define STR_LEN		1024*8

typedef unsigned char byte;


extern "C" __declspec(dllexport) void DES_Encrypt(char*  sz_encrypt)
{
	char keyString[9]; 
	strcpy(keyString, "12345678");
	des_context ctx;
	des_set_key(&ctx, (unsigned char*)keyString);



	char srcString[STR_LEN], destString[STR_LEN];
	memset(srcString, 0, STR_LEN);
	memset(destString, 0, STR_LEN);

	//int SrcLen = 4;

	int SrcLen = strlen(sz_encrypt);

	if (SrcLen % 8 != 0)
		SrcLen = ((SrcLen / 8) + 1) * 8;


	strcpy(srcString, sz_encrypt);




	int len = strlen(srcString);
	for (int i = 0; i<len; i += 8){
		unsigned char tmp[9] = { 0 };
		des_encrypt(&ctx, (unsigned char*)&srcString[i], tmp);
		memcpy(&destString[i], tmp, 8);
	}
	char outString[STR_LEN * 2];
	memset(outString, 0, STR_LEN * 2);


	for (int i = 0; i < SrcLen; i++){
		wsprintf(&outString[i * 2], "%02X", *(byte*)(destString + i));
	}
	 


	strcpy(sz_encrypt, outString);
}

extern "C" __declspec(dllexport) void DES_Decrypt(char*  sz_encrypt)
{

	int destLen = strlen(sz_encrypt);

	char keyString[9];
	strcpy(keyString, "12345678");



	char srcString[STR_LEN], destString[STR_LEN];
	char outString[STR_LEN];

	memset(srcString, 0, STR_LEN);

	memset(destString, 0, STR_LEN);
	strcpy(destString, sz_encrypt);


	memset(outString, 0, STR_LEN);
	BYTE bTmp;
	for (int i = 0; i<destLen / 2; i++){
		bTmp = destString[i * 2];
		if (bTmp>0x39)
			bTmp = bTmp - 'A' + 10;
		else
			bTmp -= 0x30;
		outString[i] = bTmp << 4;

		bTmp = destString[i * 2 + 1];
		if (bTmp>0x39)
			bTmp = bTmp - 'A' + 10;
		else
			bTmp -= 0x30;
		outString[i] += bTmp;
	}

	des_context ctx;
	des_set_key(&ctx, (unsigned char*)keyString);
	for (int i = 0; i<destLen / 2; i += 8){
		unsigned char tmp[9] = { 0 };
		des_decrypt(&ctx, (unsigned char*)&outString[i], tmp);
		memcpy(&srcString[i], tmp, 8);
	}



	strcpy(sz_encrypt, srcString);
}

written by ocean \\ tags: ,

1月 02

几年前有研究过这个类似的东西,实现Javascript里的Eval函数

C# Eval随想 云推送

新发现Roslyn更加好用,以后可以做点好玩的东西了,

研究了一下,记录下来简单的demo

Nuget添加引用

Microsoft.CodeAnalysis.CSharp

或者用Package Manager Console命令

Install-Package Microsoft.CodeAnalysis.CSharp

测试代码如下

            var text = @"
                    public class Calculator
                    {
                        public static int Evaluate() { return 3 + 2 * 55; }
                    }";

            var tree = SyntaxFactory.ParseSyntaxTree(text);

            var compilation = CSharpCompilation.Create("calc.dll", new[] { tree },
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary),
                 //references: new[] { new MetadataFileReference(typeof(object).Assembly.Location) });
                 references: new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location) }); 

            Assembly compiledAssembly;
            using (var stream = new MemoryStream())
            {
                var compileResult = compilation.Emit(stream);
                compiledAssembly = Assembly.Load(stream.GetBuffer());
            }

            var calculatorClass = compiledAssembly.GetType("Calculator");
            var evaluateMethod = calculatorClass.GetMethod("Evaluate");
            var result = evaluateMethod.Invoke(null, null).ToString();
            Console.WriteLine(result);

注意注释部分,这个地方已经有所改变,跟网上存在的方式不太一样了。

written by ocean \\ tags:

1月 01

新年的鞭炮声刚过,我还在苦逼的Coding,不过依然自得其乐。

这篇记录一下C#调用VC++的DLL里的方法

其实VC++完全一窍不通呀,不过为了新的项目,我决定拼了。顺祝自己好运

首先,建立VC++的项目,选择Win32的DLL项目

在Source Files里添加OceanTest.cpp

#include "stdafx.h"

extern "C" __declspec(dllexport) int Add(int a, int b)
{
	return a + b;
}

extern "C" __declspec(dllexport) int Add2(int a, int b)
{
	return a + b + 2;
}

里面定义了两个方法,编译之后产生一个XXX.DLL 

建立C#工程,类型任意,测试用的winform

讲刚才生成的XXX.DLL复制到bin的debug目录下

调用如下

        private void button1_Click(object sender, EventArgs e)
        {

            int c = Add(5, 7);
            int cc = Add2(5, 7);

        }


        [DllImport("XXX.dll", EntryPoint = "Add", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
        public static extern int Add(int a, int b);


        [DllImport("XXX.dll", EntryPoint = "Add2", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
        public static extern int Add2(int a, int b);

 

完美!!! 

补充一下字符串型的调用,这个和int的不太一样

C++ Code

extern "C" __declspec(dllexport) void DES_Encrypt(char*  sz_encrypt)
{ 
	strcpy(sz_encrypt, "ccccccc"); 
}

C#中定义

        [DllImport("xxx.dll", EntryPoint = "DES_Encrypt",  CallingConvention = CallingConvention.Cdecl)]
        public extern static void DES_Encrypt(StringBuilder sz_encrypt);
    }

C#调用

            var output = new StringBuilder();
            DES_Encrypt(output);

written by ocean \\ tags: