سال خوبی را برای همهی شما آرزومندم.
BloggerToCHM
سال خوبی را برای همهی شما آرزومندم.
// بازکردن دیتابیسی که از قبل رمزنگاری نشده است SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3"); cnn.Open(); // دیتابیس رمزنگاری شده. ارتباط با دیتابیس همچنان صحیح و برقرار باقی میماند cnn.ChangePassword("mypassword");
// بازکردن دیتابیسی که از قبل رمزنگاری شده SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3;Password=mypassword"); cnn.Open(); // حذف رمزنگاری از دیتابیس رمزنگاری شده cnn.ChangePassword( null as byte[] );
// SetPassword بازکردن دیتابیس رمزنگاری شده با استفاده از فراخوانی تابع SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3"); cnn.SetPassword(new byte[] { 0xFF, 0xEE, 0xDD, 0x10, 0x20, 0x30 }); cnn.Open();
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.sqlite"); cnn.Open(); cmd = new SQLiteCommand("ATTACH DATABASE 'c:\\pwd.sqlite' AS [Protected] KEY 'mypassword'", cnn); cmd.ExecuteNonQuery();
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3"); cnn.Open(); cmd = new SQLiteCommand("ATTACH DATABASE 'c:\\pwd.db3' AS [Protected] KEY X'FFEEDD102030'", cnn); cmd.ExecuteNonQuery();
PM> install-package OxyPlot.Wpf
<Window x:Class="OxyPlotWpfTests.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:oxy="http://oxyplot.org/wpf" xmlns:oxyPlotWpfTests="clr-namespace:OxyPlotWpfTests" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <oxyPlotWpfTests:MainWindowViewModel x:Key="MainWindowViewModel" /> </Window.Resources> <Grid DataContext="{Binding Source={StaticResource MainWindowViewModel}}"> <oxy:PlotView Model="{Binding PlotModel}"/> </Grid> </Window>
public class MainWindowViewModel { public PlotModel PlotModel { get; set; }
private void createPlotModel() { PlotModel = new PlotModel { Title = "سری خطوط", Subtitle = "Pan (right click and drag)/Zoom (Middle click and drag)/Reset (double-click)" }; PlotModel.MouseDown += (sender, args) => { if (args.ChangedButton == OxyMouseButton.Left && args.ClickCount == 2) { foreach (var axis in PlotModel.Axes) axis.Reset(); PlotModel.InvalidatePlot(false); } }; }
readonly LinearAxis _xAxis = new LinearAxis(); private void addXAxis() { _xAxis.Minimum = 0; _xAxis.MaximumPadding = 1; _xAxis.MinimumPadding = 1; _xAxis.Position = AxisPosition.Bottom; _xAxis.Title = "X axis"; _xAxis.MajorGridlineStyle = LineStyle.Solid; _xAxis.MinorGridlineStyle = LineStyle.Dot; PlotModel.Axes.Add(_xAxis); }
readonly LinearAxis _yAxis = new LinearAxis(); private void addYAxis() { _yAxis.Minimum = 0; _yAxis.Title = "Y axis"; _yAxis.MaximumPadding = 1; _yAxis.MinimumPadding = 1; _yAxis.MajorGridlineStyle = LineStyle.Solid; _yAxis.MinorGridlineStyle = LineStyle.Dot; PlotModel.Axes.Add(_yAxis); }
readonly LineSeries _lineSeries1 = new LineSeries(); private void addLineSeries1() { _lineSeries1.MarkerType = MarkerType.Circle; _lineSeries1.StrokeThickness = 2; _lineSeries1.MarkerSize = 3; _lineSeries1.Title = "Start"; _lineSeries1.MouseDown += (s, e) => { if (e.ChangedButton == OxyMouseButton.Left) { PlotModel.Subtitle = "Index of nearest point in LineSeries: " + Math.Round(e.HitTestResult.Index); PlotModel.InvalidatePlot(false); } }; PlotModel.Series.Add(_lineSeries1); }
readonly LineSeries _lineSeries2 = new LineSeries(); private void addLineSeries2() { _lineSeries2.MarkerType = MarkerType.Circle; _lineSeries2.Title = "End"; _lineSeries2.StrokeThickness = 2; _lineSeries2.MarkerSize = 3; _lineSeries2.MouseDown += (s, e) => { if (e.ChangedButton == OxyMouseButton.Left) { PlotModel.Subtitle = "Index of nearest point in LineSeries: " + Math.Round(e.HitTestResult.Index); PlotModel.InvalidatePlot(false); } }; PlotModel.Series.Add(_lineSeries2); }
private int _xMax; private int _yMax; private bool _haveNewPoints; private void addPoints() { var timer = new DispatcherTimer {Interval = TimeSpan.FromSeconds(1)}; var rnd = new Random(); var x = 1; updateXMax(x); timer.Tick += (sender, args) => { var y1 = rnd.Next(100); updateYMax(y1); _lineSeries1.Points.Add(new DataPoint(x, y1)); var y2 = rnd.Next(100); updateYMax(y2); _lineSeries2.Points.Add(new DataPoint(x, rnd.Next(y2))); x++; updateXMax(x); _haveNewPoints = true; }; timer.Start(); } private void updateXMax(int value) { if (value > _xMax) { _xMax = value; } } private void updateYMax(int value) { if (value > _yMax) { _yMax = value; } }
private readonly Stopwatch _stopwatch = new Stopwatch(); private void updatePlot() { CompositionTarget.Rendering += (sender, args) => { if (_stopwatch.ElapsedMilliseconds > _lastUpdateMilliseconds + 2000 && _haveNewPoints) { if (_yMax > 0 && _xMax > 0) { _yAxis.Maximum = _yMax + 3; _xAxis.Maximum = _xMax + 1; } PlotModel.InvalidatePlot(false); _haveNewPoints = false; _lastUpdateMilliseconds = _stopwatch.ElapsedMilliseconds; } }; }
When running a dotnet application differences in diverse local and production environments can make collecting diagnostics artifacts (e.g., logs, traces, process dumps) challenging. dotnet-monitor
aims to simplify the process by exposing a consistent REST API regardless of where your application is run.
<LangVersion>9.0</LangVersion>
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel; namespace System.Runtime.CompilerServices { /// <summary> /// Reserved to be used by the compiler for tracking metadata. /// This class should not be used by developers in source code. /// </summary> [EditorBrowsable(EditorBrowsableState.Never)] internal static class IsExternalInit { } }
🔹برنامهنویسان با تخصصهای مختلف چقدر حقوق میگیرند؟
🔸درآمد برنامهنویسان فریلنس در مقایسه با برنامهنویسان دائمی چگونه است؟
🔹افزایش سابقه کار چقدر بر روی درآمد برنامهنویسان تاثیرگذار است؟
🔸برنامهنویسان برای سال 99 انتظار چه میزان افزایش حقوق دارند؟
"جابویژن" امسال نیز همانند سال گذشته دومین نظرسنجی سراسری حقوق و دستمزد برنامهنویسان را برگزار کرد که در این نظرسنجی حدود 4500 نفر شرکت کردند.
در قسمت قبل دیدیم چگونه باید پروفایل کاربر را بدرستی بارگذاری کنیم. در این مقاله به مالکیت وهلهها (instance ownership) میپردازیم.
در پایان قسمت قبلی، اپلیکیشن وب را در این حالت رها کردیم:
همانطور که مشاهده میکنید با خطای زیر مواجه هستیم:
System.Data.SqlClient.SqlException: Cannot open database "OldFashionedDB" requested by the login. The login failed.
Login failed for user 'IIS APPPOOL\ASP.NET v4.0'.
این بار پیغام خطا واضح و روشن است. LocalDb با موفقیت اجرا شده و اپلیکیشن وب هم توانسته به آن وصل شود، اما این کانکشن سپس قطع شده چرا که دسترسی به وهله جاری وجود نداشته است. اکانت ApplicationPoolIdentity (در اینجا IIS APPPOOL\ASP.NET v4.0) نتوانسته به دیتابیس LocalDb وارد شود، چرا که دیتابیس مورد نظر در رشته اتصال اپلیکیشن (OldFashionedDB) وجود ندارد. عجیب است، چرا که وصل شدن به همین دیتابیس با رشته اتصال جاری در ویژوال استودیو با موفقیت انجام میشود.
همانطور که در تصویر بالا مشاهده میکنید از ابزار SQL Server Object Explorer استفاده شده است. این ابزار توسط SQL Server Data Tools معرفی شد و در نسخههای بعدی ویژوال استودیو هم وجود دارد و توسعه یافته است. چطور ممکن است ویژوال استودیو براحتی بتواند به دیتابیس وصل شود، اما اپلیکیشن وب ما با همان رشته اتصال نمیتواند دیتابیس را باز کند؟ در هر دو صورت رشته اتصال ما بدین شکل است:
Data Source=(localdb)\v11.0;Initial Catalog=OldFashionedDB;Integrated Security=True
پاسخ این است که در اینجا، دو وهله از LocalDb وجود دارد. بر خلاف وهلههای SQL Server Express که بعنوان سرویسهای ویندوزی اجرا میشوند، وهلههای LocalDb بصورت پروسسهای کاربری (user processes) اجرا میشوند. هنگامی که کاربران مختلفی سعی میکنند به LocalDb متصل شوند، برای هر کدام از آنها پروسسهای مجزایی اجرا خواهد شد. هنگامی که در ویژوال استودیو به localdb)\v11.0) وصل میشویم، وهله ای از LocalDb ساخته شده و در حساب کاربری ویندوز جاری اجرا میشود. اما هنگامی که اپلیکیشن وب ما در IIS میخواهد به همین دیتابیس وصل شود، وهله دیگری ساخته شده و در ApplicationPoolIdentity اجرا میشود. گرچه ویژوال استودیو و اپلیکیشن ما هر دو از یک رشته اتصال استفاده میکنند، اما در عمل هر کدام به وهلههای متفاوتی از LocalDb دسترسی پیدا خواهند کرد. پس مسلما دیتابیسی که توسط وهله ای در ویژوال استودیو ساخته شده است، برای اپلیکیشن وب ما در IIS در دسترس نخواهد بود.
یک مقایسه خوب از این وضعیت، پوشه My Documents در ویندوز است. فرض کنید در ویژوال استودیو کدی بنویسیم که در این پوشه یک فایل جدید میسازد. حال اگر با حساب کاربری دیگری وارد ویندوز شویم و به پوشه My Documents برویم این فایل را نخواهیم یافت. چرا که پوشه My Documents برای هر کاربر متفاوت است. بهمین شکل، وهلههای LocalDb برای هر کاربر متفاوت است و به پروسسها و دیتابیسهای مختلفی اشاره میکنند.
به همین دلیل است که اپلیکیشن وب ما میتواند بدون هیچ مشکلی روی IIS Express اجرا شود و دیتابیس را باز کند. چرا که IIS Express درست مانند LocalDb یک پروسس کاربری است. IIS Express توسط ویژوال استودیو راه اندازی میشود و روی حساب کاربری جاری اجرا میگردد، پس پروسس آن با پروسس خود ویژوال استودیو یکسان خواهد بود و هر دو زیر یک اکانت کاربری اجرا خواهند شد.
درک ماهیت مشکل جاری، راه حالهای مختلفی را برای رفع آن بدست میدهد. از آنجا که هر راه حل مزایا و معایب خود را دارد، بجای معرفی یک راه حال واحد چند راهکار را بررسی میکنیم.
اگر مشکل، حسابهای کاربری مختلف است، چرا خود IIS را روی کاربر جاری اجرا نکنیم؟ در این صورت ویژوال استودیو و اپلیکیشن ما هر دو به یک وهله از LocalDb وصل خواهند شد و همه چیز بدرستی کار خواهد کرد. ایجاد تغییرات لازم نسبتا ساده است. IIS را اجرا کنید و Application Pool مناسب را انتخاب کنید، یعنی همان گزینه که برای اپلیکیشن شما استفاده میشود.
قسمت Advanced Settings را باز کنید:
روی دکمه سه نقطه کنار خاصیت Identity کلیک کنید تا پنجره Application Pool Identity باز شود:
در این قسمت میتوانید از حساب کاربری جاری استفاده کنید. روی دکمه Set کلیک کنید و نام کاربری و رمز عبور خود را وارد نمایید. حال اگر اپلیکیشن را مجددا اجرا کنید، همه چیز باید بدرستی اجرا شود.
خوب، معایب این رویکرد چیست؟ مسلما اجرای اپلیکیشن وب روی اکانت کاربری جاری، ریسکهای امنیتی متعددی را معرفی میکند. اگر کسی بتواند اپلیکیشن وب ما را هک کند، به تمام منابع سیستم که اکانت کاربری جاری به آنها دسترسی دارد، دسترسی خواهد داشت. اما اجرای اپلیکیشن مورد نظر روی ApplicationPoolIdentity امنیت بیشتری را ارائه میکند، چرا که اکانتهای ApplicationPoolIdentity دسترسی بسیار محدودتری به منابع سیستم محلی دارند. بنابراین استفاده از این روش بطور کلی توصیه نمیشود، اما در سناریوهای خاصی با در نظر داشتن ریسکهای امنیتی میتواند رویکرد خوبی باشد.
یک راه حال دیگر استفاده از قابلیت instance sharing است. این قابلیت به ما این امکان را میدهد تا یک وهله LocalDb را بین کاربران یک سیستم به اشتراک بگذاریم. وهله به اشتراک گذاشته شده، توسط یک نام عمومی (public name) قابل دسترسی خواهد بود.
سادهترین راه برای به اشتراک گذاشتن وهلههای LocalDb استفاده از ابزار SqlLocalDB.exe است. بدین منظور Command Prompt را بعنوان مدیر سیستم باز کنید و فرمان زیر را اجرا نمایید:
sqllocaldb share v11.0 IIS_DB
Data Source=(localdb)\.\IIS_DB;Initial Catalog=OldFashionedDB;Integrated Security=True
create login [IIS APPPOOL\ASP.NET v4.0] from windows; exec sp_addsrvrolemember N'IIS APPPOOL\ASP.NET v4.0', sysadmin
معایب این روش چیست؟ مشکل اصلی در این رویکرد این است که پیش از آنکه اپلیکیشن ما بتواند به وهله مشترک دسترسی داشته باشد، باید وهله مورد نظر را راه اندازی و اجرا کنیم. بدین منظور، حساب کاربری ویندوزی که مالکیت وهله را دارد باید به آن وصل شود و کانکشن را زنده نگه دارد، در غیر اینصورت وهله LocalDb قابل دسترسی نخواهد بود.
از آنجا که نسخه کامل SQL Server Express بعنوان یک سرویس ویندوزی اجرا میشود، شاید بهترین راه استفاده از همین روش باشد. کافی است یک نسخه از SQL Server Express را نصب کنیم، دیتابیس مورد نظر را در آن بسازیم و سپس به آن متصل شویم. برای این کار حتی میتوانید از ابزار جدید SQL Server Data Tools استفاده کنید، چرا که با تمام نسخههای SQL Server سازگار است. در صورت استفاده از نسخههای کامل تر، رشته اتصال ما بدین شکل تغییر خواهد کرد:
Data Source=.\SQLEXPRESS;Initial Catalog=OldFashionedDB;Integrated Security=True
create login [IIS APPPOOL\ASP.NET v4.0] from windows; exec sp_addsrvrolemember N'IIS APPPOOL\ASP.NET v4.0', sysadmin