مطالب
فعالسازی امکانات Refactoring افزونه‌ی Roslynator در VSCode
یکی از قابلیت‌های افزونه‌ی C# for Visual Studio Code پس از نگارش 1.10.0 آن، امکان بارگذاری افزونه‌های مخصوص Roslyn است که قابلیت‌های Refactoring را به همراه دارند؛ مانند افزونه‌ی معروف و جامع Roslynator. البته هنوز افزونه‌های Analyzers مبتنی بر Roslyn، با VSCode سازگاری ندارند که قرار است در نگارش‌های آتی افزوده شوند. در این مطلب، نحوه‌ی فعالسازی افزونه‌های Roslyn refactoring ثالث را بررسی خواهیم کرد.


فعالسازی قدم به قدم Roslyn refactoring افزونه‌ی Roslynator

الف) فایل VSIX آن‌را از اینجا دریافت کنید و سپس پسوند آن‌را به zip تغییر دهید.
ب) این فایل zip را در پوشه‌ای مشخص باز کنید.
ج) پس از باز کردن این فایل zip، دو فایل Roslynator.VisualStudio.Core.dll و Roslynator.VisualStudio.dll آن‌را حذف کنید. این فایل‌ها مخصوص نگارش کامل ویژوال استودیو هستند و در صورت وجود، با سیستم بارگذاری افزونه‌های OmniSharp تداخل می‌کنند.
د) در آخر مسیر زیر را گشوده:
%USERPROFILE%/.omnisharp
و سپس فایل جدید omnisharp.json را با محتوای ذیل، در آن مسیر ایجاد کنید:
{
  "RoslynExtensionsOptions": {
    "LocationPaths": [
      "C:\\lib\\roslynator"
    ]
  }
}
که در اینجا مسیر ذکر شده، به پوشه‌ای اشاره می‌کند که فایل zip افزونه را در آنجا گشوده‌اید (به ذکر \\ هم دقت داشته باشید؛ تا فایل json نهایی، به درستی تشکیل شود).

اکنون اگر VSCode را اجرا کنید، شاهد افزوده شدن امکانات Refactoring مخصوص افزونه‌ی Roslynator به لیست Refactoring پیش‌فرض OmniSharp خواهید بود:



خودکار سازی دریافت، نصب و فعالسازی Roslyn refactoring افزونه‌ی Roslynator

مراحل فوق را می‌توان تبدیل به یک اسکریپت پاورشل کرد که با هر بار اجرای آن، به صورت خودکار کار دریافت و نصب این افزونه صورت گیرد:
Write-Host "Download, unzip and enable Roslynator for Visual Studio Code"

$name = "josefpihrt.Roslynator2017"
$url = "https://marketplace.visualstudio.com/items?itemName=$name"
$currentDir = $PSScriptRoot
$file = "$currentDir\Roslynator.zip"

$pattern = "<script class=`"vss-extension`" defer=`"defer`" type=`"application\/json`">(.*?)<\/script>"
$regex = [regex]"(?m)$pattern"
Write-Host "Grab the home page of the $name."
$dom = (New-Object Net.WebClient).DownloadString($url); 
if($dom -and $dom -match $pattern) 
{
    $matches = $regex.Match($dom)
    $jsonText = $matches[0].Groups[1]

    $json = ConvertFrom-Json $jsonText

    $version = $Json.versions[0].version # Parse the json in the page for the latest version number
    $parts = $name.Split(".")
    $publisher = $parts[0]
    $package = $parts[1]

    # Assemble the url for the vsix package
    $packageUrl = "https://marketplace.visualstudio.com/_apis/public/gallery/publishers/$publisher/vsextensions/$package/$version/vspackage"
    Write-Host "Download the vsix package: $packageUrl"
    (New-Object Net.WebClient).DownloadFile($packageUrl, $file)

    Write-Host "Using $currentDir as the current dir."
    Write-Host "Unzip $file."
    $shellApp = new-object -com shell.application 
    $zipFile = $shellApp.namespace($file) 
    $destination = $shellApp.namespace($currentDir) 
    $destination.Copyhere($zipFile.items(), 0x14)# overwrite and be silent

    Write-Host "Delete VS specific files. Otherwise they will interfere with the MEF services inside OmniSharp."
    Remove-Item "$currentDir\Roslynator.VisualStudio.Core.dll","$currentDir\Roslynator.VisualStudio.dll", "$currentDir\Roslynator.VisualStudio.pkgdef"

    $omnisharpJsonFilePath = "$env:USERPROFILE\.omnisharp\omnisharp.json";
    Write-Host "Create $omnisharpJsonFilePath file."
    $omnisharpJson = @" 
{{
  "RoslynExtensionsOptions": {{
    "LocationPaths": [
      "{0}"
    ]
  }}
}}
"@ -f $currentDir -Replace "\\","\\"
    $omnisharpJson | Out-File "$omnisharpJsonFilePath" -Confirm

    Write-Host "Done!"
}
else
{
    Write-Host "Failed to find the packageUrl!"
}
کدهای فوق را با نام فرضی update.ps1 ذخیره کنید (و یا از اینجا دریافت کنید: update.zip ). سپس می‌توانید آن‌را با اجرای دستور update.ps1\.، اجرا کرده و به صورت خودکار شاهد این مراحل باشید:
PS D:\Prog\1396\RoslynatorVSCode> .\update.ps1
Download, unzip and enable Roslynator for Visual Studio Code
Grab the home page of the josefpihrt.Roslynator2017.
Download the vsix package: https://marketplace.visualstudio.com/_apis/public/gallery/publishers/josefpihrt/vsextensions/Roslynator2017/1.7.0/vspackage
Using D:\Prog\1396\RoslynatorVSCode as the current dir.
Unzip D:\Prog\1396\RoslynatorVSCode\Roslynator.zip.
Delete VS specific files. Otherwise they will interfere with the MEF services inside OmniSharp.
Create C:\Users\Vahid\.omnisharp\omnisharp.json file.

Confirm
Are you sure you want to perform this action?
Performing the operation "Output to File" on target "C:\Users\Vahid\.omnisharp\omnisharp.json".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"):
Done!
ابتدا صفحه‌ی اصلی این افزونه دریافت می‌شود. سپس از داخل آن، پارامترهای مخصوص دانلود افزونه استخراج و آدرس دریافت نهایی آن تشکیل می‌شود.
در ادامه این افزونه دریافت شده و در پوشه‌ی جاری باز خواهد شد. سپس فایل omnisharp.json نیز به صورت خودکار تشکیل و مقدار دهی می‌شود.
اکنون اگر VSCode را اجرا کنید، همه چیز آماده بوده و امکانات این افزونه در دسترس خواهند بود.
اشتراک‌ها
کتابخانه nucleus
Nucleus is a web-based interactive development environment (IDE) that is currently under development. It will include native language support for fusion files such as .fjs, .fhtml, and .fcss along with fusion transcompiling. It will also offer a jTypes plugin that adds support for .jt and .fjt files, and built-in jTypes precompiling from .jt or .fjt to .js files.  Demo
کتابخانه nucleus
اشتراک‌ها
اکستنشنی برای پیاده سازی CQRS , EventSourcing در Orleans

Orleankka is a functional extension for Microsoft Orleans framework. It provides a message-based API similar to Akka/ProtoActor, carefully layered on top of Microsoft Orleans (that's what in a name). Orleankka is an excellent choice for use-cases which can benefit from composable, uniform communication interface, such as CQRS, event-sourcing, FSM, etc.

اکستنشنی برای پیاده سازی CQRS , EventSourcing در Orleans
مطالب
WF:Windows Workflow #۳
اضافه کردن عناصر رویه ای 

در این قسمت به بررسی عناصر رویه‌ای مانند دستورات IF,While,Assign می‌پردازیم .
در این بخش توضیحات را با یک مثال آغاز می‌کنیم. در این مثال می‌خواهیم به بررسی کار با زمان بپردازیم.
قبل از هر کاری، ابتدا نیاز به دو متغیر داریم؛ یکی کار شمارنده را بر عهده داشته و دیگری وظیفه ذخیره کردن ساعت را بر عهده دارد. برای انجام این کار، ابتدا مانند شکل زیر عمل می‌کنیم :

همانطور که در شکل مشاهده می‌کنید دو متغیر به نام‌های Counter و numberBells تعریف شده است و نوع هر دو، از جنس Int32 می‌باشد و در محدوده Sequence  قرار گرفته‌اند. در قسمت پیش فرض، مقدار مورد نظر را تعیین کرده‌ایم.
نکته : این مورد را در نظر داشته باشید که قبل از تعریف Variables باید حتما یک Sequence در صفحه داشته باشیم تا بتوانیم محدوده متغیر مورد نظر را مشخص کنیم. 
حال مانند قسمت پیش، ابتدا باید از  Toolbox، قسمت Control Flow، کنترل  Sequence را به داخل صفحه کشید و پس از آن می‌توانیم از سایر کنترل‌ها استفاده نمائیم. پس از این کار، از قسمت  Primitives کنترل  WriteLine را به درون Sequence انتقال می‌دهیم٬ سپس مانند شکل زیر یک کنترل IF که در قسمت Control Flow موجود می‌باشد را انتخاب کرده و به زیر کنترل WriteLine انتقال می‌دهیم. مانند شکل زیر:


همانطور که در شکل مشاهده می‌کنید، در کنترل IF در قسمت Condition شرط مورد نظر را مشخص می‌کنیم. در قسمت THEN از کنترل Assign استفاده شده است. از این کنترل وقتی استفاده می‌شود که قصد انتساب یک مقدار را به متغیری داریم. این کنترل در قسمت Primitives  موجود است.
حال مانند شکل زیر عمل کرده و یک کنترل While را به زیر IF اضافه می‌کنیم؛ مانند شکل زیر :

کنترل While از دو قسمت تشکیل شده٬ شرط حلقه و بدنه آن. در قسمت شرط، مانند دستور IF عمل کرده و در قسمت بدنه، دستورات مورد نظر را مشخص می‌کنیم. در حلقه موجود تا زمانیکه متغیر  Counter از numberBelss کوچکتر مساوی باشد، این حلقه اجرا می‌شود و در طی این جریان، ابتدا مقدار متغیر counter چاپ می‌شود٬ سپس یکی به مقدار آن اضافه می‌شود؛ البته با یک وقفه مشخص. برای اینکه بتوانیم در هر قسمت Workflow وقفه ایجاد کنیم، از کنترل Delay استفاده می‌شود. این کنترل دارای خاصیتی است به نام Duration. در این قسمت می‌توان میزان وقفه را مشخص نمود.
برای مقدار دادن به این خاصیت، کنترل Delay را انتخاب کرده٬ سپس از قسمت Properties در VS2010 یا VS2012 می‌توان به خاصیت Duration مقدار داد.
TimeSpan.FromSeconds(1)
از این طریق وقفه‌ای که در بر نامه ایجاد می‌شود، یک ثانیه می‌باشد.

در این قسمت هم چک می‌شود که اگر ساعت جاری سیستم بیشتر از ۱۸ بود مقدار «عصر بخیر» چاپ شود، در غیر اینصورت مقدار «روز خوب» چاپ می‌شود.
نکته : در قسمت بدنه حلقه While حتما باید از کنترل Sequence استفاده شود٬ در غیر این صورت امکان تعریف بدنه حلقه While وجود ندارد.  
مطالب
برنامه نویسی پیشرفته JavaScript - قسمت 2 - ماهیت انواع داده‌ای و حوزه دسترسی به متغیرها

مقادیر پایه (Primitive Values) و ارجاعی (Reference Values)

در جاوا اسکریپت، متغیرها شامل داده‌هایی از نوع پایه و یا ارجاعی می‌باشند. مقادیر String ، Number ، Boolean ، Null و Undefined به عنوان مقادیر پایه محسوب می‌گردند. در این نوع متغیرها تغییرات، مستقیما بر روی مقدار ذخیره شده در متغیر اعمال می‌شوند. اشیاء نیز که از مجموعه‌ای از مقادیر پایه ساخته شده‌اند، مقادیر ارجاعی نامیده می‌شوند. در این نوع مقادیر، شما به اشاره‌گری از شیء دسترسی دارید. بنابراین تغییرات مستقیما بر روی داده‌های ذخیره شده اعمال نمی‌شوند. به مثال‌های زیر توجه کنید:

var num1 = 10;
var num2 = num1;
alert("Num1=" + num1 + ", Num2=" + num2);

num2 = 20;
alert("Num1=" + num1 + ", Num2=" + num2);

num1 = 30;
alert("Num1=" + num1 + ", Num2=" + num2);

خروجی :

"Num1=10, Num2=10"

"Num1=10, Num2=20"

"Num1=30, Num2=20"


همانطور که از خروجی مثال فوق پیداست، در انتساب num1 به num2 ، مقدار num1 در num2 کپی شده‌است. بنابراین تغییراتی که بر روی num1 یا num2 صورت می‌گیرد، مستقیما بر روی مقدار ذخیره شده در هر یک از این متغیرها تاثیر می‌گذارد. رفتار مقادیر پایه همیشه به همین صورت می‌باشد.

var obj1 = new Object();
obj1.num = 10;
var obj2 = obj1;
alert("Obj1.Num=" + obj1.num + ", Obj2.Num=" + obj2.num);

obj2.num = 20;
alert("Obj1.Num=" + obj1.num + ", Obj2.Num=" + obj2.num);

obj1.num = 30;
alert("Obj1.Num=" + obj1.num + ", Obj2.Num=" + obj2.num);

خروجی :

"Obj1.Num=10, Obj2.Num=10"

"Obj1.Num=20, Obj2.Num=20"

"Obj1.Num=30, Obj2.Num=30"


با استفاده از نوع ارجاعی Object می‌توانیم اشیاء جدیدی را ایجاد کنیم و ویژگی‌هایی را به صورت پویا به آن‌ها اختصاص دهیم. همانطور که قبلا گفته شد، اشیاء از نوع ارجاعی می‌باشند و حاوی اشاره‌گری به مقادیر ذخیره شده می‌باشند. بنابراین انتساب obj1 به obj2 به معنای انتساب اشاره‌گر obj1 به obj2 می‌باشد. به عبارتی دیگر obj2 به همانجایی اشاره می‌کند که obj1 نیز اشاره می‌نماید. پس هر تغییری که بر روی ویژگی‌های obj1 رخ دهد، obj2 نیز تاثیرات آن را می‌بیند و بالعکس. همانطور که در خروجی مشاهده می‌نمایید، در مرحله‌ی اول obj1 به obj2 نسبت داده شد، پس مقدار ویژگی num برای هر دو آنها یکسان میباشد. در مرحله‌ی دوم، مقدار ویژگی num را در obj2 تغییر دادیم؛ ولی مقدار این ویژگی، در obj1 نیز تغییر نمود. در مرحله‌ی سوم نیز همان اتفاقات مرحله‌ی دوم تکرار شد.

با توجه به مثالهای فوق قطعا به تفاوت‌های مقادیر پایه و ارجاعی پی بردید. همچنین در یک نمونه‌ی کوچک و ساده نیز، یکی از روش‌های ایجاد شیء را که استفاده از نوع ارجاعی Object می‌باشد، مشاهده نمودید. این دانسته‌ها مقدمه ای بر شروع برنامه نویسی شیء گرا می‌باشند. ولی قبل از شروع برنامه نویسی شیء گرا در جاوا اسکریپت، به بررسی نکات و تکنیک‌های دیگری می‌پردازیم.

توجه:

به انواع پایه، انواع داده‌ای مقداری یا اولیه نیز گفته می‌شود.


فراخوانی با مقدار (Call by Value)

در این نوع فراخوانی، آرگومان‌ها از نوع مقادیر پایه هستند. بنابراین هر تغییری که بر روی آرگومان‌ها در تابع رخ دهد، هیچ تاثیری بر روی آرگومان‌های ارسالی در زمان فراخوانی تابع ندارند. به مثال زیر توجه کنید:

function primitive(a, b) {
a += 100;
b += 200;
alert("a=" + a + ", b=" + b);
}

var x = 300, y = 400;
primitive(x, y);
alert("x=" + x + ", y=" + y);

خروجی :

"a=400, b=600"

"x=300, y=400"


x و y دو متغیر پایه می‌باشند، بنابراین تابع فوق به صورت مقداری فراخوانی شده‌است. یعنی مقدار آرگومان‌های x و y در آرگومان‌های a و b کپی می‌شوند. پس هر تغییری که بر روی a و b رخ دهد، هیچ تاثیری بر روی x و y ندارد. همچنین با توجه به توضیحی که در مورد مقادیر پایه داده شد، تغییرات مستقیما بر روی داده‌ی ذخیره شده در متغیر اعمال میشود. بنابراین تغییراتی که در تابع فوق بر روی a و b رخ داد، مستقیما مقادیر a و b را تغییر داده‌است وهیچ ارتباطی به x و y ندارد. البته توجه داشته باشید که حتی اگر نام آرگومان‌های تابع با آرگومان‌های ارسالی یکسان بود و یا حتی اگر تابع مقداری را به عنوان خروجی بر می‌گرداند، هیچ تفاوتی را در خروجی برنامه فوق مشاهده نمی‌کردید.


فراخوانی با ارجاع (Call by Reference)

در این نوع فراخوانی، آرگومان‌ها از نوع مقادیر ارجاعی هستند. بنابراین هر تغییری که بر روی آرگومان‌ها در تابع رخ دهد، بر روی آرگومان‌های ارسالی در زمان فراخوانی تابع نیز تاثیر می‌گذارند. به مثال زیر توجه کنید:

function reference(obj) {
obj.a += 100;
obj.b += 200;
alert("obj.a=" + obj.a + ", obj.b=" + obj.b);
}

var calc = new Object();
calc.a = 300;
calc.b = 400;

reference(calc);
alert("calc.a=" + calc.a + ", calc.b=" + calc.b);

خروجی :

"obj.a=400, obj.b=600"

"calc.a=400, calc.b=600"


calc یک مقدار ارجاعی است که به عنوان آرگومان ورودی به تابع ارسال می‌شود و اشاره‌گر خود را به obj اختصاص می‌دهد. بنابراین obj به همان آدرسی اشاره می‌کند که calc اشاره می‌نماید. پس هر تغییری که بر روی obj رخ دهد، calc نیز تاثیرات آن را مشاهده می‌نماید. همانطور که در خروجی نیز مشاهده می‌نمایید، تغییرات صورت گرفته در تابع به calc نیز منعکس شده است.


حوزه دسترسی به متغیرها (Variable Scope)

متغیر‌های محلی (Local Variables)

در اکثر زبان‌های برنامه نویسی، متغیرهایی که در یک بلاک کد تعریف می‌شوند، به صورت محلی و فقط در همان بلاک کد قابل دسترسی  می‌باشند. به این متغیرها، متغیرهای محلی می‌گویند که با خاتمه‌ی اجرای بلاک کد، از بین خواهند رفت و دیگر قابل دسترسی نمی‌باشند. اما در جاوا اسکریپت حوزه‌ی اجرایی متغیرها کمی متفاوت می‌باشد. به مثال زیر توجه کنید:

for (var i = 1; i <= 5; i++) {
var sqr = i * i;
alert(sqr);
}

alert(i);
alert(sqr);

خروجی :

1
4
9
16
25
6   // alert(i) out of for
25   // alert(sqr) out of for


متغیرهای i و sqr داخل حلقه‌ی for تعریف شده‌اند و منطقا نباید خارج از این حلقه قابل دسترسی باشند. ولی با توجه به خروجی فوق، مشاهده نمودید که متغیرهای i و sqr، نه تنها خارج از این حلقه قابل شناسایی می‌باشند، بلکه آخرین مقدار خود را نیز حفظ نموده‌اند. در جاوا اسکریپت، یک متغیر محلی زمانی مفهوم پیدا می‌کند که در داخل یک تابع تعریف شود. به مثال زیر توجه کنید:

function sqr(num) {
var sum = num * num;
return sum;
}

var n = 4;
alert(sqr(n));
alert(num); // Error: num is not defined
alert(sum); // Error: sum is not defined

خروجی :

16

Error: num is not defined

Error: sum is not defined

همانطور که مشاهده می‌کنید، متغیرهای num و sum به صورت محلی در تابع فوق تعریف شده‌اند؛ بنابراین خارج از تابع قابل دسترسی نمی‌باشند و موجب بروز خطا می‌گردند.


متغیرهای عمومی (Global Variables)

در جاوا اسکریپت، متغیرهایی که خارج از تابع تعریف می‌گردند، به شیء window نسبت داده می‌شوند و عمومی می‌باشند. به عبارتی دیگر این متغیرها به عنوان یک ویژگی از شیء window تعریف می‌شوند و در تمامی توابع و بلاک‌های کد قابل دسترسی می‌باشند. به مثال زیر توجه کنید:

var color = "Red";

function setColor() {
color = "Blue";
}

alert(color);
setColor();
alert(color);

خروجی :

"Red"

"Blue"


در مثال فوق، متغیر color به صورت عمومی تعریف شده‌است. بنابراین در کل برنامه قابل دسترسی می‌باشد. در alert اول مقدار فعلی متغیر color یعنی “Red” نمایش می‌یابد. سپس با فراخوانی تابع، مقدار این متغیر تغییر می‌کند. در alert دوم مقدار تغییر یافته‌ی متغیر color نمایش خواهد یافت. حال به مثال زیر توجه کنید:

var color = "Red";

function getColor() {
var color = "Blue";
return color;
}

alert(color);
alert(getColor());
alert(color);

خروجی :

"Red"

"Blue"

"Red"


در مثال فوق، ابتدا یک متغیر color به صورت عمومی یا Global تعریف شده است. در تابع getColor نیز یک متغیر color به صورت local یا محلی تعریف شده است. زمانی که در alert تابع getColor فراخوانی می‌شود، متغیر color مقداردهی می‌گردد. این مقداردهی برای متغیر محلی صورت گرفته است و هیچ ربطی به متغیر color که به صورت عمومی تعریف شده است ندارد.

جهت تعریف متغیر در جاوا اسکریپت، از کلمه‌ی کلیدی var استفاده می‌شود. اما تعریف متغیر در جاوا اسکریپت اجباری نمی‌باشد و می‌توان یک متغیر را مقداردهی نمود بدون آنکه تعریف شده باشد. در صورتی که متغیر با var اعلان نشود، آن متغیر به شیء window نسبت داده می‌شود و ماهیت عمومی پیدا می‌کند. به مثال زیر توجه کنید:

function sum(a, b) {
c = a + b;
}

sum(20, 30);
alert(c);

خروجی :

50


همانطور که مشاهده می‌کنید، متغیر c بدون تعریف شدن مورد استفاده قرار گرفته است. با اینکه به صورت محلی مقداردهی گردیده است، ولی چون توسط var اعلان نشده است، به شیء window نسبت داده شده و ماهیت عمومی پیدا کرده است. 

مطالب
نگهداری رشته ها (String) در حافظه به صورت Encrypt
در همین سایت در بخش لینک‌های ارسالی ، لینکی توسط آقای امیر هاشم زاده به اشتراک گذاشته شده بود با عنوان  "چرا هکرها نوع داده String را دوست دارند" ؛ مقاله ای بود در سایت CodeProject که در آن روش هایی که هکرها توسط آن می‌توانند اطلاعات حساس نرم افزار را که در قالب String در حافظه ذخیره شده اند را بررسی نمایند.
اصل مطلب را می‌توانید اینجا مطالعه کنید.

در دات نت فریم ورک کلاسی با عنوان SecureString وجود دارد که توسط آن می‌توان عبارات رشته ای که دارای اطلاعات حساس می‌باشند را به صورت رمز گذاری شده در حافظه ذخیره نمود.

نمونه ای از استفاده این تابع را در زیر مشاهده میکنید:
public class Example
{
    public static void Main()
    {
        .
        SecureString securePwd = new SecureString();
        ConsoleKeyInfo key;

        Console.Write("Enter password: ");
        do {
           key = Console.ReadKey(true);

           // بررسی میشود که کلید فشرده شده جزو حروف الفبا می‌باشد یا کلید دیگری است
           if (((int) key.Key) >= 65 && ((int) key.Key <= 90)) {
              // کاراکتر مربوط به کلید فشرده شده به انتهای متغیر سکوراسترینک اضافه می‌شود
              securePwd.AppendChar(key.KeyChar);
              Console.Write("*");
           }   
        // خروج از حلقه در صورت فشردن کلید اینتر
        } while (key.Key != ConsoleKey.Enter);
        Console.WriteLine();

        try
        {
            MessageBox.Show(securePwd);
        }
        catch (Win32Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

در کدهای بالا رمز عبور از کاربر دریافت شده و در متغیر securepwd که شئی از کلاس SecureString می‌باشد ذخیره می‌شود.پس از آن شئی SecureString عبارت مربوطه را به صورت رمز گذاری شده در حافظه ذخیره میکند.
در این روش ابتدا مقدار کلید فشرده شده در متغیر Key که از نوع ConsoleKeyInfo تعریف شده ذخیره می‌شود. بعد از آن مقدار آن بررسی شده و اگر جزو حروف الفبای انگلیسی بود به انتهای متغیر securepwd افزوده می‌شود. این کار با متد AppendChar انجام می‌شود. این عملیات تا فشرده شدن کلید Enter ادامه پیدا میکند.
مطالب
تبدیل HTML به PDF با استفاده از کتابخانه‌ی iTextSharp

روش متداول کار با کتابخانه‌ی iTextSharp ، ایجاد شیء Document ، سپس ایجاد PdfWriter برای نوشتن در آن، گشودن سند و ... افزودن اشیایی مانند Paragraph ، PdfPTable ، PdfPCell و غیره به آن است و در نهایت بستن سند. راه میانبری هم برای کار با این کتابخانه وجود دارد و آن هم استفاده از امکانات فضای نام iTextSharp.text.html.simpleparser آن می‌باشد. به این ترتیب می‌توان به صورت خودکار، یک محتوای HTML را تبدیل به فایل PDF کرد.

مثال : نمایش یک متن HTML ساده انگلیسی
using System.Diagnostics;

using System.IO;
using iTextSharp.text;
using iTextSharp.text.html.simpleparser;
using iTextSharp.text.pdf;

namespace HeadersAndFooters
{
class Program
{
static void Main(string[] args)
{
using (var pdfDoc = new Document(PageSize.A4))
{
PdfWriter.GetInstance(pdfDoc, new FileStream("Test.pdf", FileMode.Create));
pdfDoc.Open();

var html = @"<span style='color:blue'><b>Testing</b></span>
<i>iTextSharp's</i> <u>HTML to PDF capabilities</u>";
var parsedHtmlElements = HTMLWorker.ParseToList(new StringReader(html), null);

foreach (var htmlElement in parsedHtmlElements)
{
pdfDoc.Add(htmlElement);
}
}

//open the final file with adobe reader for instance.
Process.Start("Test.pdf");
}
}
}


نکته‌ی جدید کد فوق، استفاده از متد HTMLWorker.ParseToList است. به این ترتیب parser کتابخانه‌ی iTextSharp وارد عمل شده و html تعریف شده را به معادل المان‌های بومی خودش تبدیل می‌کند؛ مثلا تبدیل به chunk یا pdfptable و امثال آن. در نهایت در طی یک حلقه، این عناصر به صفحه اضافه می‌شوند.
البته باید دقت داشت که HTMLWorker امکان تبدیل عناصر پیچیده، تودرتو و چندلایه HTML را ندارد؛ اما بهتر از هیچی است!

همه‌ی این‌ها خوب! اما به درد ما فارسی زبان‌ها نمی‌خورد. همین متغیر html فوق را با یک متن فارسی جایگزین کنید، چیزی نمایش داده نخواهد شد. البته این هم نکته دارد که در ادامه ذکر خواهد شد.
جهت نمایش متون فارسی نیاز است تا نکات ذکر شده در مطلب «فارسی نویسی و iTextSharp» رعایت شوند که شامل:
- تعیین صریح قلم
- تعیین encoding
- استفاده از عناصر دربرگیرنده‌ای است که خاصیت RunDirection را پشتیبانی می‌کنند؛ مانند PdfPCell و غیره


به این ترتیب خواهیم داشت:
using System.Diagnostics;

using System.IO;
using iTextSharp.text;
using iTextSharp.text.html.simpleparser;
using iTextSharp.text.pdf;
using iTextSharp.text.html;

namespace HeadersAndFooters
{
class Program
{
static void Main(string[] args)
{
using (var pdfDoc = new Document(PageSize.A4))
{
PdfWriter.GetInstance(pdfDoc, new FileStream("Test.pdf", FileMode.Create));
pdfDoc.Open();

//روش صحیح تعریف فونت
FontFactory.Register("c:\\windows\\fonts\\tahoma.ttf");

StyleSheet styles = new StyleSheet();
styles.LoadTagStyle(HtmlTags.BODY, HtmlTags.FONTFAMILY, "tahoma");
styles.LoadTagStyle(HtmlTags.BODY, HtmlTags.ENCODING, "Identity-H");

var html = @"<span style='color:blue'><b>آزمایش</b></span>
کتابخانه <i>iTextSharp</i> <u>جهت بررسی فارسی نویسی</u>";
var parsedHtmlElements = HTMLWorker.ParseToList(new StringReader(html), styles);

PdfPCell pdfCell = new PdfPCell { Border = 0 };
pdfCell.RunDirection = PdfWriter.RUN_DIRECTION_RTL;

foreach (var htmlElement in parsedHtmlElements)
{
pdfCell.AddElement(htmlElement);
}

var table1 = new PdfPTable(1);
table1.AddCell(pdfCell);
pdfDoc.Add(table1);
}

//open the final file with adobe reader for instance.
Process.Start("Test.pdf");
}
}
}

همانطور که ملاحظه می‌کنید ابتدا قلمی در cache قلم‌های این کتابخانه ثبت می‌شود (FontFactory.Register). سپس نوع قلم و encoding آن توسط یک StyleSheet تعریف شده و به HTMLWorker.ParseToList ارسال می‌گردد و در نهایت به کمک یک المان دارای RunDirection، در صفحه نمایش داده می‌شود.



نکته:
ممکن است که به متغیر html ، یک table ساده html را نسبت دهید. در این حالت پس از تنظیم style یاد شده، در هر سلول این html table ، متون فارسی به صورت معکوس نمایش داده خواهند شد که این هم یک نکته‌ی کوچک دیگر دارد:

foreach (var htmlElement in parsedHtmlElements)

{
if (htmlElement is PdfPTable)
{
var table = (PdfPTable)htmlElement;
table.RunDirection = PdfWriter.RUN_DIRECTION_RTL;
foreach (var row in table.Rows)
{
foreach (var cell in row.GetCells())
{
cell.RunDirection = PdfWriter.RUN_DIRECTION_RTL;
}
}
}

pdfCell.AddElement(htmlElement);
}

در قسمتی که قرار است المان‌های معادل به pdfCell اضافه شوند، آن‌ها را بررسی کرده و RunDirection آن‌ها را RTL خواهیم کرد.


کاربردها:
بدیهی است این حالت برای تهیه گزارشات پیشرفته‌تر برای مثال تهیه قالب‌هایی که در حین تهیه PDF ، قسمت‌هایی از آن‌ها توسط برنامه نویس Replace می‌شوند، بسیار مناسب است.
همچنین مطلب «بارگذاری یک یوزرکنترل با استفاده از جی‌کوئری» و متد RenderUserControl مطرح شده در آن که در نهایت یک قطعه کد HTML را به صورت رشته به ما تحویل می‌دهد، می‌تواند جهت تهیه گزارش‌های پویایی که برای مثال قسمتی از آن یک GridView بایند شده حاصل از یک یوزر کنترل است،‌ مورد استفاده قرار گیرد.


اشتراک‌ها
کتابخانه DoFilter

DoFilter is a Full Responsive Bootstrap Multipurpose Filtering and Shorting plugin built on Latest Version of Bootstrap Framework (v3.3.7), HTML5, CSS3 and jQuery. Its wonderful features can be used to Filtering and Shorting your website content as like Portfolio, Service, Team, Blog, Products, Pricing, FAQ etc. Also you can customize it for Filtering and Shorting any your website content.

DoFilter is a Full Responsive Isotope Multipurpose Filtering and Shorting plugin. Filtering can hide and show item elements with the filter option. Items that match that filter will be shown. DoFilter Responsive Isotope Multipurpose Filtering and Shorting can rearrange the order of item elements based on their data. Items that do not match will be hidden.

There are 19+ filter styles with 100% responsive design. Indeed, you will be able to showcase your content on mobile devices such as smart phones and tablets. It has many features like CSS3 and jQuery animations, single and multiple Shorting and Filtering. All the codes are clean and well organized. Also have proper help documentation. It looks great with all types of devices. 

کتابخانه DoFilter
اشتراک‌ها
بهترین کنفرانس های مهندسی نرم افزار در سال 2021

If you want to stay in touch with the latest developments in any field, you should be aware of the conferences and events regarding those topics. Thanks to the pandemic, all the conferences and events have taken the online route. Well, the best part is that it has become accessible to everyone. You do not even have to apply for official leaves to attend them. 

بهترین کنفرانس های مهندسی نرم افزار در سال 2021