1398-08-09 23:49 ایجاد و دسترسی به پراپرتی فایل و پوشه
zahmah

 
سلام و وقت بخیر.
آیا میشه یک Property یا Attribute جدید برای یک فایل یا پوشه تعریف کرد? (منظورم Archive و امثال اینهاست)
ولی این Attribute جدید باشد و بشود آدرس فایل یا توضیحاتی را در آن ست کرد یا از آن خواند.
1398-08-10 18:38
حاجی شریفی
مؤسس سایت
 
سلام
بله! البته اگر فرمت درایوتان NTFS باشد.

فایل سیستم NTFS مفهومی دارد به نام A lternate D ata S treams که اجازه میدهد برای هر فایل بینهایت اطلاعات اضافه نام دار نگهداری کنید.

برخی API های ویندوز مانند CreateFile در مسیر های NTFS و بعد نام فایل با یک کالن/دونقطه نام این stream الحاقی را دریافت میکنند.
یعنی نام ali.txt به جریان stream خود یک فایل اشاره میکند و نام ali.txt:mystream1 به جریان داده الحاقی به نام mystream1 اشاره میکند که درست مانند یک فایل قابل خواندن و نوشتن است و میتوانید هر دیتایی در آنها ذخیره کنید.

بدیهی است با Delete فایل اصلی کلیه stream ها الحاقی هم حذف خواهند شد و با Copy فایل اصلی این stream ها هم کپی میشوند.
تنها نکته در Copy فایل به درایوهای غیر NTFS است (مانند FAT32) که در این مواقع stream های الحاقی کپی نشده و به نوعی از فایل حذف میشوند.

توابع توکار دات نت مستقیم و خودکار از ADS ها پشتیبانی نمیکنند ولی در واقع هیچ مشکلی وجود ندارد.
شما میتوانید handler ها را با API های ویندوز استخراج کنید و به کلاس ها و توابع دات نت تحویل دهید و به راحتی هم کار میکند.
همچنین میتوانید از کتابخانه های dll که برای این کار نوشته شده استفاده کنید.
مانند WindowsAPICodePack یا نمونه جدیدتر Trinet.Core.IO.Ntfs و...

موفق باشید.
1398-08-10 23:05
zahmah

 
با سلام
با تشکر از پاسخ های خوب شما

من از WindowsAPICodePack استفاده کردم و میخواستم در پراپرتی Comment آن مطلبی ست کنم اما فقط در مورد فایل های jpg امکانپذیر بود(البته نه به شکل مطالبی که در بالا گفته اید).
//Set
var shellFile = ShellFile.FromParsingName(file_path);
ShellPropertyWriter set_Property = shellFile.Properties.GetPropertyWriter();
set_Property.WriteProperty(SystemProperties.System.Comment, file_path);
set_Property.Close();

//Read
var shellFile = Microsoft.WindowsAPICodePack.Shell.ShellObject.FromParsingName(file_path);
var fileComment = shellFile.Properties.GetProperty(SystemProperties.System.Comment).ValueAsObject.ToString();


اگر امکانش باشد قطعه کدی در مورد ست کردن و خواندن پراپرتی (هم فایل و هم پوشه) بگذارید
البته همه نوع فایلی...
ببخشید!
1398-08-12 11:49
حاجی شریفی
مؤسس سایت
 
سلام
آن موردی که شما میگویید از ویژگی های برخی File-Fromat است و عمومیت نداشته و در فرمت هایی که همچین ویژگی هایی دارند، حالت یک-شکل و یکپارچه هم ندارد.
قابلیت ADS از ویژگی های File-System خود NTFS است و به تمام فایل های روی این سیستم فایل به یک شکل اعمال میشود و مدیریت آن مستقیم بر عهده خود NTFS است.
محتویات این ADS ها جداگانه ذخیره میشوند و با محتویات فایل اصلی ادقام نمیشود و در برنامه های استفاده کننده از فایل اصلی تاثیری ندارد.
ولی خوب درهرصورت مختص NTFS است و باید پارتیشن مورد نظر چنین فرمت شده باشد.

نمونه کد با نصب بسته Trinet.Core.IO.Ntfs
void  Main()
{
System.IO.File.WriteAllText( "D:\\ali.txt", "any text ..." ) ;

//Write
var ads1 = Trinet.Core.IO.Ntfs.FileSystem.GetAlternateDataStream( "D:\\ali.txt", "mystream1", System.IO.FileMode.Create ) ;
using (var stream1 = ads1.OpenWrite())
using (var writer1 = new System.IO.StreamWriter(stream1))
{
writer1.Write( "<doc>my-data</doc>" ) ;
}

//Read
var ads2 = Trinet.Core.IO.Ntfs.FileSystem.GetAlternateDataStream( "D:\\ali.txt", "mystream1", System.IO.FileMode.OpenOrCreate ) ;
using (var stream2 = ads2.OpenRead())
using (var reader2 = new System.IO.StreamReader(stream2))
{
string data = reader2.ReadToEnd();
Console.WriteLine( data ) ;
}

Console.ReadLine();
}


نمونه کد با نصب بسته CodeFluentRuntimeClient
void  Main()
{
System.IO.File.WriteAllText( "D:\\ali.txt", "any text ..." ) ;

//Write
CodeFluent.Runtime.BinaryServices.NtfsAlternateStream.WriteAllText( "D:\\ali.txt:mystream1", "<doc>my-data</doc>" ) ;

//Read
string data = CodeFluent.Runtime.BinaryServices.NtfsAlternateStream.ReadAllText( "D:\\ali.txt:mystream1" ) ;
Console.WriteLine( data ) ;

Console.ReadLine();
}


در ضمن باید دقت کنید که برخی نرم افزار در کار با یک فایل و ویرایش آن ( مانند ویرایش فایل نمونه ali.txt ) بجای Update فایل ، خود را راحت میکنند و فایل را Delete و مجدد با اطلاعات جدید Create میکنند.
اگر فایل اصلی با همچین برنامه ای تغییر کند و Save شود ( بدلیل Delete و Create فایل مادر ) تمام stream های الحاقی فایل حذف خواهد شد.

خلاصه آنکه ، مجدد هشدار داده و یادآوری میکنم که امکان دارد بعد ویرایش و Save فایل اصلی ( با توجه به نرم افزار مورد استفاده ) به یکباره تمام stream های الحاقی فایل مذکور حذف شود.
همچنین با آپلود فایل در اینترنت و الحاق به ایمیل و کپی در درایوهای غیر NTFS و... این stream ها منتقل نخواهد شد.
شما نباید اطلاعات حیاتی و مهمی در این stream ها نگهداری کنید.

موفق باشید.
1398-08-17 23:34
zahmah

 
سلام
متاسفانه نتوانستم ازش استفاده کنم. در واقع dll اش را نتوانستم پیدا کنم.
طبق گفته حضرتعالی ما دو فایل خواهیم داشت. نمیشه در دل خود فایل به نحوی آدرس رو ذخیره کرد؟ من آدرس فایل مبدا رو توی سیستم مقصد نیاز دارم.
1398-08-18 01:27
حاجی شریفی
مؤسس سایت
 
سلام
نقل قول نوشته شده توسط: zahmah
... در واقع dll اش را نتوانستم پیدا کنم ...

روی نام package ها لینک شان را دادم!
https://www.nuget.org/packages/CodeFluentRuntimeClient
https://www.nuget.org/packages/Trinet.Core.IO.Ntfs

مگر تا حالا از بسته های nuget استفاده نکرده اید؟
چطور از EF استفاده میکنید؟

راه اول:
به اینترنت وصل میشوید و از منوی Tools>NuGet Package Manager>Package Manager Console اقدام کرده و در کنسول خط فرمانی که باز میشود فرمان نصب را تایپ میکنید:
Install-Package CodeFluentRuntimeClient -Version 1.0.0.844
یا
Install-Package Trinet.Core.IO.Ntfs -Version 4.1.1


راه دوم:
به اینترنت وصل میشوید و از منوی Tools>NuGet Package Manager>Manage NuGet Package for Solution اقدام کده و در فرمی که باز میشود به برگه Browse رفته و نام بسته Trinet.Core.IO.Ntfs یا CodeFluentRuntimeClient را جستجو کرده و روی دکمه Install کلیک میکنید.

نقل قول نوشته شده توسط: zahmah
... دو فایل خواهیم داشت ...

این با مفهوم فایل متفاوت است، چیزی جایی دیده نمیشود، نوعی دیتای اضافه و دلخواه برای فایل است.
1398-08-20 22:43
zahmah

 
سلام
اگه اشتباه نکنم نمونه کدهای بالا در مورد یک فایل doc هستش
امکانش هست همین کد رو در مورد یک فایل ویدیویی بنویسید که آدرسش رو توی فایل داده الحاقی ذخیره کنه؟
1398-08-21 02:18
حاجی شریفی
مؤسس سایت
 
سلام
نقل قول نوشته شده توسط: zahmah
امکانش هست همین کد رو در مورد یک فایل ویدیویی بنویسید که ...

همانطورکه قبلا هم اشاره کردم، ADS مکانیزم داخلی سیستم فایل NTFS است.
این یعنی در لایه خیلی پایین تری از آن عمل میکند که اصلا فرمت و داده های فایل اصلی در آن معنی داشته باشد.
برای هر نام و پسوند فایلی میتوانید از ADS استفاده کنید. در سطح درایور و سیستم-فایل NTFS همه فایل ها txt, dox, xls, mp4, mp3, wav, pdf, exe, jpg و... و... هیچ فرق و اهمیتی ندارد، برای سیستم-فایل/FS همه اینها فقط یک مشت string(نام) + مشتی byte(داده) بی معنی هستند.

مثل آن است که بگویید فرمان File.Delete برای doc چیست وحالا File.Delete برای ویدیو فرمانش چیست(؟!)
سیستم-فایل/FS میتواند یک فایل را به شرطی که Open نباشد ( ومجوزهای لازم را داشته باشید ) Delete کند، در این کار هیچ فرقی بین txt, doc, mp4, exe و... برایش ندارد.( اصلا متوجه فرمت داخلی فایل نمیشود و برایش مهم نیست چه برنامه و چه شرکتی چه چیزی و به شکلی در آن ذخیره کرده )

ADS هیچ تاثیری در داده های اصلی فایل ندارد، این اطلاعات اضافه کاملا بطور جداگانه (وبه نوعی مخفی) توسط خود سیستم-فایل ذخیره و مدیریت میشود.

نقل قول نوشته شده توسط: zahmah
... که آدرسش رو توی فایل داده الحاقی ذخیره کنه؟

یعنی چه؟ مثلا در داده الحاقی فایل C:\file.mp4 بیایید و ذخیره کنید "C:\file.mp4" ؟!!
1398-09-09 00:16
zahmah

 
سلام
هنگام استفاده از Trinet پیام خطای زیر رو نشون میده
The name 'Trinet' does not exist in the current context

توی دایرکتوری پروژه ام هم در پوشه packages پوشه Trinet.Core.IO.Ntfs.4.1.1 موجود هست. دلیلش چیه؟
1398-09-09 23:12
حاجی شریفی
مؤسس سایت
 
سلام
نوع پروژه تان چیست؟ (ASP WebForm, WinForm, WinWPF یا ...)
خیلی وقت است این خطا را ندیده ام
در رایانه خودتان و در Visual Studio این خطا رخ میدهد یا برنامه را کامپایل میکنید و به رایانه دیگری میبرید و سپس رخ میدهد؟

این خطا می تواند از عدم کامپایل صحیح باشد.
پوشه obj و bin را در پروژه تان، کامل delete کنید.

از عدم تطبیق صحیح نسخه dotNetFramework یا dotNetCore در برنامه و dll های مورد استفاده هم شاید رخ دهد.
dll را خودتان دستی اضافه و Add-Reference کرده اید یا با همان فرمان خودکار nuget که بالاتر گفته بودم انجام دادید؟
(فرمان خودکار Install-Package یا فرم دیداری Manage NuGet Package)
نسخه دات نت فریم ورک پروژه تان را بالاتر ببرید.
Reference فایل dll را حذف کنید.
مجدد از طریق فرمان Install-Package یا فرم دیداری Manage NuGet Package فایل dll را به پروژه تان اضافه کنید.

شبیه مورد قبل از منشاء مشکل در Reference ها میتواند باشد.
دقت کنید که در Reference های پروژه خطا و آیکون هشدار و... نیامده باشد.

درصورت ادامه مشکل نسخه ساده شده ای از برنامه تان را آپلود کنید.
1398-09-12 22:05
zahmah

 
سلام
حل شد ممنون.

جهت اطلاع از وجود یا عدم وجود این اطلاعات اضافه چکار باید کرد؟ کد زیر جواب نداد.
if(File.Exists( "ali.txt:mystream1" ))
1398-09-14 00:43
حاجی شریفی
مؤسس سایت
 
سلام
باید از توابع موجود در همان dll ها استفاده کنید، مانند :
bool  isExists = Trinet.Core.IO.Ntfs.FileSystem.AlternateDataStreamExists( "C:\\ali.txt", "mystream1" ) ;
1399-01-14 10:47
zahmah

 
سلام
من برای ایجاد Property از Trinet.Core.IO.Ntfs استفاده میکنم. روی سیستم خودم جواب میدهد اما پس از ساخت ستاپ و نصب روی سیستم مشتری Property برای فایل یا پوشه نمیسازد.
و در ضمن هیچ error ی هم نمیدهد. مشکل از کجاست؟
از ستاپ ساز ویژوال استودیو 2013 استفاده میکنم و در پروژه ستاپ هم فایل dll آن به نام Trinet.Core.IO.Ntfs.dll در پوشه Application Folder توسط خود ستاپ ساز اضافه شده است
1399-01-14 13:10
حاجی شریفی
مؤسس سایت
 
سلام
اگر پروژه در رایانه خودتان کار میکند و فقط از همین کامپونت استفاده کرده اید و مثلا دیتابیس و اتصال به سایت خاصی و... ندارید.
چند احتمال وجود دارد.

دقت کنید که نسخه مناسب dotNetFramework در رایانه مقصد نصب باشد.
با برنامه کوچک زیر میتوانید نسخه نصب شده دات نت را مشاهده کنید.
http://33x.ir/osversion

مورد بعدی میتوانید مربوط به عدم دسترسی امنیتی برنامه شما به آن مسیر مشخص از هارد-دیسک باشد.
مثلا اغلب ویندوزهای فعلی بطور پیشفرض دسترسی ویرایش در مسیر Program Files و Windows و... را نمیدهند.
یکبار برنامه را با راست-کلیک و فرمان Run As Administrator اجرا کنید و نتیجه کارکرد را مجدد بررسی کنید.

ومورد دیگر همانطور که پیش تر هم اشاره کردم، این ویژگی مختص فایل-سیستم NTFS است.
روی درایوی که میخواهید این ADS ها را در آن ایجاد کنید، راست-کلیک و Properties بزنید و مطمئن شوید که فایل-سیستم درایو NTFS باشد.


نکته آخر آنکه، در مورد عدم نمایش خطا دقت کنید که به قول خودم(!) آشغال ها را زیر فرش نریخته باشید.
منظورم آن است که دستور try-catch ای نداشته باشید که catch اش خالی باشد و هیچ کدی نداشته باشد.
این خیلی بد است، اغلب یعنی اینکه میخواهید خودتان را فریب دهید.
دستور داخل catch باید کار مفیدی انجام دهد، برای نمونه راه کاری دومی را برای مسئله امتحان کند، لاگ خطا را در فایل ذخیره کند یا پیام مناسب را به کاربر نشان دهد و...و...
دقت کنید همچین شرایطی در کدتان نداشته باشید.
try 
{
// code ...
// code ...
// code ...
// code ...
// code ...
}
catch { } // <<< empty block


,موفق باشید.
1399-01-15 15:09
zahmah

 
سلام
برنامه من کارش این است که پوشه هایی را به استوریج منتقل می کند و همزمان در بانک هم اطلاعات مربوط به آن را ذخیره می کند.

علت استفاده ام از Trinet.Core.IO.Ntfs هم بخاطر ذخیره آدرس و بعضی ویژگیهای دیگر پوشه ها در قالب Property جدید جهت استفاده در استوریج شبکه دیگری که در شهر دیگری است و با شبکه ما ارتباط ندارد می باشد.(هدف یکسان سازی آدرس یک پوشه در هر دو استوریج است)

نحوه ذخیره در استوریج هم طبق راهنمایی قبلی که از خودتان گرفته بودم در قالب یک پوشه روت استوریج که Map Network Drive شده می باشد.

اینها را نوشتم شاید در پیدا کردن مشکلم بهتان کمک کند یا راه حل بهتری باشد
ممنون
1399-01-15 15:37
zahmah

 
ایجاد Property با WindowsAPICodePack راحتتر نیست؟ آیا احتمال ندارد که اگر از WindowsAPICodePack استفاده کنم مشکلم حل شود؟

واقعیتش نحوه کدزنی WindowsAPICodePack جهت ایجاد Property را پیدا نکردم
1399-01-15 21:40
zahmah

 
ایجاد Property با WindowsAPICodePack راحتتر نیست؟ آیا احتمال ندارد که اگر از WindowsAPICodePack استفاده کنم مشکلم حل شود؟

واقعیتش نحوه کدزنی WindowsAPICodePack جهت ایجاد Property را پیدا نکردم
1399-01-15 22:00
حاجی شریفی
مؤسس سایت
 
سلام
چند موردی که میتوانست باعث عدم کارکرد شود را خدمت تان عرض کردم.
مورد واضح دیگری به ذهنم نمیرسد.

بطور قطع برنامه شما بخش های زیادی دارد.
امکان دارد خطا در هر جایی مخفی شده باشد.
مثلا شاید if ای قبل از کد باشد که کلا اجازه اجرا شدن کد مربوطه را ندهد ...
و...
یک برنامه خیلی کوچک دو سه خطی مستقل ، حتی یک ConsoleApp بسازید که ADS ای را برای فایلی ذخیره و بخواند.
تا مکانیزم ADS خود را تست کنید.

برای کدهایتان لاگ قرار دهید تا بدانید روند اجرا از کجا عبور کرده یا عبور نکرده و چه خطاهایی رخ داده

نقل قول نوشته شده توسط: zahmah

علت استفاده ام از Trinet.Core.IO.Ntfs هم بخاطر ذخیره آدرس و بعضی ویژگیهای دیگر پوشه ها در قالب Property جدید جهت استفاده در استوریج شبکه دیگری که در شهر دیگری است و با شبکه ما ارتباط ندارد می باشد

شاید بد نباشد ، یک جور دیتابیس کوچک تک فایلی کنار Storage تان داشته باشید.
مثلا یک تک فایل sqlite یا xml یا json که نقش دیتابیس را بازی کند و با نام مشخص در مسیر مشخص هر Storage باشد.
یعنی یک جدول مانند ساده از string مسیرها و فیلد هایی که میخواهید نگهداری کنید
این خیلی بهتر و شفاف تر است ، میتوانید دیتابیس را مشاهده کنید ، ببنید درست ذخیره شده، صحیح خوانده میشود و...
JSON
{
db: [

{
"path": "\\Folder1\\Folder2",
"is_sync": true,
"last_date": "2020-04-03"
},

{
"path": "\\Folder3",
"is_sync": false,
"last_date": "2020-04-01"
}

...
]
}


نقل قول نوشته شده توسط: zahmah

ایجاد Property با WindowsAPICodePack راحتتر نیست؟ آیا احتمال ندارد که اگر از WindowsAPICodePack استفاده کنم مشکلم حل شود؟

واقعا بعید میدانم مشکل شما از این باشد.

بسته WindowsAPICodePack بسیار قدیمی است ، مایکروسافت در یک زمانی داد و بعد دیگر بخیالش شد.
بعد ها افراد متعددی سورس را مجدد کامپایل کردند و در nuget منتشر کردند و از کار آنها هم سالها میگذرد.
https://www.nuget.org/packages?q=windows+api+code+pack

سورس اش هنوز در اینترنت موجود است و حتی الآن، مطالعه اش حتما حاوی نکات جالبی است.
ولی متصل کردن پروژه تان به یک بسته قدیمی ، که دیگر مالکی هم ندارد، کار جالبی نیست.
ضمن اینکه طبق تجربه ، به احتمال زیاد در جایی از کد خودتان به نکته کوچکی دقت نکرده اید.
موفق باشید.
1399-01-18 23:12
zahmah

 
سلام
حل شد...
مشکل از سطح دسترسی به درایو بود که باید در تب Security درایو مورد نظر، Full Control میگذاشتم.