.NET ডকুমেন্ট লিস্ট আপলোডার নমুনা

জেফ ফিশার, Google Data APIs টিম
জানুয়ারী 2008

ভূমিকা: নমুনার সুযোগ

প্রোগ্রাম ইন্টারফেসের স্ক্রিনশট

স্যাম্পল এক্সিকিউটেবল ডাউনলোড করুন

ডকুমেন্টস লিস্ট ডেটা এপিআই সম্পর্কে একটি চমৎকার জিনিস হল যে এটি ডেভেলপারদের এমন ব্যবহারকারীদের জন্য মাইগ্রেশন টুল তৈরি করতে দেয় যারা এখনও Google ডক্সে স্থায়ী হচ্ছেন। এই API ব্যবহার করার উদ্দেশ্যে, আমি একটি .NET 2.0 আপলোডার অ্যাপ্লিকেশন তৈরি করতে .NET ক্লায়েন্ট লাইব্রেরি ব্যবহার করেছি, যথাযথভাবে "DocList Uploader" শিরোনাম। আপনি সাবভারশন থেকে আপলোডারের উত্স পেতে পারেন।

এই নমুনাটি একজন ব্যবহারকারীর জন্য তাদের কম্পিউটার থেকে Google ডক্সে তাদের নথিগুলি স্থানান্তর করা সহজ করার উদ্দেশ্যে করা হয়েছে৷ এটি ব্যবহারকারীদের তাদের Google অ্যাকাউন্টে লগ ইন করতে এবং তারপর সমর্থিত ফাইলগুলিকে টেনে আনতে এবং ড্রপ করতে দেয় যা তারপর স্বয়ংক্রিয়ভাবে আপলোড হয়। নমুনা ফাইল আপলোড করার জন্য উইন্ডোজ এক্সপ্লোরার শেলে একটি ডান ক্লিক মেনু বিকল্প যোগ করার বিকল্পও প্রদান করে। এই নমুনাটি Apache 2.0 লাইসেন্সের অধীনে সরবরাহ করা হয়েছে, তাই আপনি এটিকে আপনার নিজের প্রোগ্রামগুলির জন্য একটি সূচনা পয়েন্ট হিসাবে ব্যবহার করতে পারবেন।

.NET ফ্রেমওয়ার্ক ব্যবহার করে নমুনার কিছু আচরণ কীভাবে সম্পন্ন করা হয়েছিল তা দেখানোর জন্য এই নিবন্ধটি বোঝানো হয়েছে। এটি বেশিরভাগই প্রাসঙ্গিক বিভাগ থেকে টীকাযুক্ত কোড স্নিপেট নিয়ে গঠিত। এই নিবন্ধটি কীভাবে অ্যাপ্লিকেশনটির ফর্ম এবং অন্যান্য UI উপাদানগুলি তৈরি করতে হয় তা কভার করে না, কারণ সেখানে অনেক ভিজ্যুয়াল স্টুডিও নিবন্ধ রয়েছে যা এর জন্য বিশদে রয়েছে। UI উপাদানগুলি কীভাবে কনফিগার করা হয়েছে সে সম্পর্কে আপনি যদি কৌতূহলী হন, আপনি ক্লায়েন্ট লাইব্রেরি ডাউনলোড করে এবং "clients\cs\samples\DocListUploader" সাবডিরেক্টরিটি দেখে নিজেই প্রকল্প ফাইলটি লোড করতে পারেন।

একটি সিস্টেম ট্রে অ্যাপ তৈরি করা হচ্ছে

ট্রে অ্যাপের উদাহরণ

মাইগ্রেশন টুলগুলি সাধারণত অপারেটিং সিস্টেমে নিরবচ্ছিন্নভাবে চলতে সক্ষম হয়, ব্যবহারকারীকে খুব বেশি বিভ্রান্তি ছাড়াই ওএস যা করতে সক্ষম তা প্রসারিত করে। উইন্ডোজে এই ধরনের একটি টুল গঠন করার একটি উপায় হল এটিকে তাদের টাস্কবারে বিশৃঙ্খলার পরিবর্তে সিস্টেম ট্রে থেকে রান আউট করা। এটি ব্যবহারকারীদের একটি নির্দিষ্ট কাজ সম্পাদন করার প্রয়োজন হলে শুধুমাত্র প্রোগ্রামটি খোলার পরিবর্তে প্রোগ্রামটি ক্রমাগত চালিয়ে যাওয়ার সম্ভাবনা অনেক বেশি করে তোলে। এটি এই নমুনার জন্য একটি বিশেষ উপযোগী ধারণা কারণ এটি ডিস্কে প্রমাণীকরণ শংসাপত্র সংরক্ষণ করার প্রয়োজন নেই।

একটি সিস্টেম ট্রে অ্যাপ্লিকেশন এমন একটি যা প্রাথমিকভাবে সিস্টেম ট্রেতে শুধুমাত্র একটি NotifyIcon দিয়ে চলে (টাস্কবারের ঘড়ির কাছাকাছি অঞ্চল)। এই ধরনের একটি অ্যাপ্লিকেশন ডিজাইন করার সময়, মনে রাখবেন যে আপনি প্রকল্পের মূল রূপটি ব্যবহারকারীর সাথে যোগাযোগ করতে চান না। পরিবর্তে, অ্যাপ্লিকেশন চালানোর সময় প্রদর্শন করার জন্য একটি পৃথক ফর্ম তৈরি করুন। এর কারণ কিছুক্ষণের মধ্যেই পরিষ্কার হয়ে যাবে।

আমার উদাহরণে আমি দুটি ফর্ম তৈরি করেছি: হিডেনফর্ম, বেশিরভাগ যুক্তি সহ অ্যাপ্লিকেশনটির প্রধান ফর্ম এবং বিকল্প ফর্ম একটি ফর্ম যা ব্যবহারকারীকে কিছু বিকল্প কাস্টমাইজ করতে এবং তাদের Google অ্যাকাউন্টে সাইন ইন করতে দেয়৷ আমি হিডেনফর্মে DocListNotifyIcon নামে একটি NotifyIcon যোগ করেছি এবং আমার নিজের আইকন দিয়ে কাস্টমাইজ করেছি। হিডেনফর্মটি ব্যবহারকারীর দ্বারা না দেখা যায় তা নিশ্চিত করার জন্য, আমি এর অপাসিটি 0%, এর উইন্ডোস্টেটকে মিনিমাইজ করে এবং এর ShowInTaskbar প্রপার্টি False-এ সেট করেছি।

সাধারণত, যখন একটি প্রোগ্রাম সিস্টেম ট্রে থেকে ফুরিয়ে যায়, তখন অ্যাপ্লিকেশনটি বন্ধ করলে প্রোগ্রামটি বন্ধ হওয়ার কথা নয়, বরং এর পরিবর্তে যেকোন সক্রিয় ফর্মগুলিকে লুকিয়ে রাখুন এবং শুধুমাত্র NotifyIconটি দৃশ্যমান রেখে দিন৷ এটি করার জন্য আমাদের ফর্মের "ফর্মক্লোজিং" ইভেন্টটিকে নিম্নরূপ ওভাররাইড করতে হবে:

private void OptionsForm_FormClosing(object sender, FormClosingEventArgs e)
{
    if(e.CloseReason == CloseReason.UserClosing) {
        this.Hide();
        e.Cancel = true;
    }
}

আমরা সম্ভবত ফর্মটি লুকিয়ে রাখতে চাই যখন ব্যবহারকারী এটিকে ছোট করে, যেহেতু টাস্কবারে জায়গা নেওয়ার কোনও কারণ নেই কারণ আমাদের ইতিমধ্যে একটি বিজ্ঞপ্তি আইকন রয়েছে৷ এটি নিম্নলিখিত বিট কোড দিয়ে করা যেতে পারে:

private void OptionsForm_Resize(object sender, EventArgs e)
{
    if (this.WindowState == FormWindowState.Minimized)
    {
        this.Hide();
    }
}

এখন যেহেতু আমরা ব্যবহারকারীকে OptionsForm বন্ধ করার অনুমতি দিই না, তাই আমরা শুধু একটি উদাহরণ রাখতে পারি যা আমাদের HiddenForm এর সাথে আবদ্ধ। যখন আমরা আবার OptionsForm প্রদর্শন করতে চাই, তখন আমরা সহজভাবে এর Show method বলতে পারি।

যেহেতু এই অ্যাপ্লিকেশনটির প্রধান ফর্ম, হিডেনফর্ম, ব্যবহারকারীর কাছে দৃশ্যমান নয়, তাই আমাদের তাদের আসলে আমাদের অ্যাপ্লিকেশন থেকে প্রস্থান করার একটি উপায় দিতে হবে। আমি অ্যাপ্লিকেশনটি বন্ধ করার জন্য একটি ToolStripMenuItem সহ NotifyIcon-এ একটি প্রসঙ্গ মেনু যোগ করার জন্য নির্বাচন করেছি। ক্লিক হ্যান্ডলার লিখতে সহজ, শুধু হিডেনফর্মের Close পদ্ধতিতে কল করুন।

বেলুন টিপস

অনেক সিস্টেম ট্রে অ্যাপ্লিকেশন ব্যবহারকারীর সাথে একটি বেলুনের টিপ দেখিয়ে যোগাযোগ করে, যা NotifyIcon থেকে উদ্ভূত একটি গোলাকার বুদবুদের মতো দেখায়। বুদবুদ নিম্নলিখিত হিসাবে দেখানো যেতে পারে:

DocListNotifyIcon.ShowBalloonTip(10000, "Title", "Example Text", ToolTipIcon.Info);

প্রথম যুক্তি হল বুদবুদ প্রদর্শনের জন্য মিলিসেকেন্ডে সময়ের পরিমাণ। মনে রাখবেন যে OS এই ক্ষেত্রের জন্য সর্বনিম্ন এবং সর্বাধিক পরিমাণ সময় দেবে, যা যথাক্রমে 10 এবং 30 সেকেন্ড। দ্বিতীয় এবং তৃতীয় আর্গুমেন্টগুলি বুদবুদের জন্য একটি শিরোনাম এবং কিছু বিষয়বস্তু নির্দিষ্ট করে৷ শেষ যুক্তি আপনাকে বুদবুদের উদ্দেশ্য ব্যাখ্যা করার জন্য একটি আইকন বাছাই করতে দেয়।

নথি আপলোড করা হচ্ছে

একটি নথি আপলোড করা সোজা। অধিকাংশ কাজ DocumentsService অবজেক্টের UploadDocument পদ্ধতি দ্বারা সম্পন্ন হয়। এই প্রক্রিয়াটি ডকুমেন্ট লিস্ট API-এর জন্য বিকাশকারীর গাইডে আরও স্পষ্টভাবে ব্যাখ্যা করা হয়েছে।

service = new DocumentsService("DocListUploader");
((GDataRequestFactory) service.RequestFactory).KeepAlive = false;
service.setUserCredentials(username, password);

প্রথমে, DocumentsService অবজেক্টটি আরম্ভ করতে হবে এবং ব্যবহারকারীর শংসাপত্র অবশ্যই প্রদান করতে হবে। একাধিক ফাইল আপলোড করার সময় কিছু সমস্যা প্রতিরোধ করার জন্য, "কিপ-অ্যালাইভ" HTTP শিরোনামটি নিষ্ক্রিয় করা হয়েছে কারণ এটি .NET ফ্রেমওয়ার্কের সাথে কিছু সমস্যার কারণ হিসাবে পরিচিত।

lastUploadEntry = service.UploadDocument(fileName, null);

এই স্নিপেটটি ফাইলটিকে স্ট্রিং fileName এ থাকা পাথে আপলোড করে। দ্বিতীয় যুক্তিটি শূন্য হওয়ার ইঙ্গিত দেয় যে Google ডক্স ফাইলের নামটি মূল ফাইলের নামের মতোই হবে৷

ড্র্যাগ এবং ড্রপ হ্যান্ডলিং

আপলোড করা সহজ করার জন্য, ব্যবহারকারীকে তাদের ফোল্ডারগুলি থেকে ফাইলগুলিকে আপলোড করার জন্য অ্যাপ্লিকেশনটিতে টেনে আনতে দেওয়া এবং ড্রপ করতে দেওয়া বোধগম্য। প্রথম ধাপ হল একটি ফাইল থেকে ড্রপ অপারেশনের অনুমতি দেওয়া, নিচের কোডটি কার্সার পরিবর্তন করে নির্দেশ করবে যে ড্রপ অনুমোদিত:

private void OptionsForm_DragEnter(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
    {
        e.Effect = DragDropEffects.Copy;
    }
}

একবার ফাইল বা ফাইলের গ্রুপ ড্রপ হয়ে গেলে, ড্রপ করা প্রতিটি ফাইলের মধ্য দিয়ে গিয়ে এবং এটি আপলোড করে আমাদের অবশ্যই সেই ইভেন্টটি পরিচালনা করতে হবে:

private void OptionsForm_DragDrop(object sender, DragEventArgs e)
{
    string[ fileList = (string[) e.Data.GetData(DataFormats.FileDrop);

    foreach (string file in fileList)
    {
      mainForm.UploadFile(file);
    }
}

নথি তালিকা

সার্ভার থেকে নথিগুলির একটি তালিকা পাওয়া ব্যবহারকারীকে তারা ইতিমধ্যে আপলোড করেছে তা মনে করিয়ে দেওয়ার একটি চমৎকার উপায়৷ নীচের স্নিপেটটি সার্ভার থেকে সমস্ত নথি পুনরুদ্ধার করার জন্য আমরা আগে শুরু করা DocumentsService অবজেক্ট ব্যবহার করে।

public DocumentsFeed GetDocs()
{
    DocumentsListQuery query = new DocumentsListQuery();
    DocumentsFeed feed = service.Query(query);
    return feed;
}

এই ডেটা কল্পনা করার একটি সুবিধাজনক উপায় হল একটি ListView ব্যবহার করে। আমি OptionsFormDocList নামের একটি ListView যোগ করেছি। এটিকে আরও সুন্দর করার জন্য, আমি বিভিন্ন নথির ধরনকে চিত্রিত করার জন্য আইকনগুলির একটি কাস্টম ইমেজলিস্টও তৈরি করেছি। নিচের কোডটি উপরের ফিড থেকে প্রাপ্ত তথ্যের সাথে লিস্টভিউকে পপুলেট করে:

public void UpdateDocList()
{

    DocList.Items.Clear();


    DocumentsFeed feed = mainForm.GetDocs();


    foreach (DocumentEntry entry in feed.Entries)
    {
        string imageKey = "";
        if (entry.IsDocument)
        {
            imageKey = "Document.gif";
            
        }
        else if (entry.IsSpreadsheet)
        {
            imageKey = "Spreadsheet.gif";
        }
        else
        {
            imageKey = "Presentation.gif";
        }

        ListViewItem item = new ListViewItem(entry.Title.Text, imageKey);
        item.SubItems.Add(entry.Updated.ToString());
        item.Tag = entry;
        DocList.Items.Add(item); 
    }

    foreach (ColumnHeader column in DocList.Columns)
    {
        column.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
    }
}

imageKey ভেরিয়েবল প্রতিটি সারির জন্য সংশ্লিষ্ট ImageList-এর কোন ছবি ব্যবহার করা উচিত তা বেছে নেয়। মূল এন্ট্রি সংরক্ষণ করতে এখানে Tag বৈশিষ্ট্য ব্যবহার করা হয়েছে, যা পরবর্তীতে নথিতে ক্রিয়াকলাপ সম্পাদনের জন্য উপযোগী হতে পারে। সবশেষে, লিস্টভিউতে কলামের প্রস্থ স্বয়ংক্রিয় ফর্ম্যাট করতে AutoResize পদ্ধতি ব্যবহার করা হয়।

ব্রাউজারে নথি খোলা

যেহেতু এই নথিগুলি Google ডক্সে সংরক্ষিত আছে, তাই ব্যবহারকারীকে তাদের ব্রাউজারে নথিটি দেখতে দেওয়া ভাল। উইন্ডোজে এটি করার জন্য অন্তর্নির্মিত কার্যকারিতা রয়েছে:

using System.Diagnostics;

private void OpenSelectedDocument()
{
    if (DocList.SelectedItems.Count > 0)
    {
        DocumentEntry entry = (DocumentEntry) DocList.SelectedItems[0].Tag;
        Process.Start(entry.AlternateUri.ToString());
    }
}

এখানে আমরা Tag প্রপার্টি থেকে আসল এন্ট্রি পুনরুদ্ধার করি, তারপর Process.Start কল করতে নির্বাচিত নথির AlternateUri ব্যবহার করি। বাকিটা .NET ফ্রেমওয়ার্কের জাদু দ্বারা পরিচালিত হয়।

একটি শেল প্রসঙ্গ মেনু যোগ করা হচ্ছে

শেলের প্রসঙ্গ মেনুতে একটি আইটেম যোগ করার সবচেয়ে সহজ উপায় হল রেজিস্ট্রি পরিবর্তন করা। আমাদের যা করতে হবে তা হল HKEY_CLASSES_ROOT এর অধীনে একটি এন্ট্রি তৈরি করা যা আমাদের আবেদনের দিকে নির্দেশ করে৷ নোট করুন যে ব্যবহারকারী মেনু আইটেমটিতে ক্লিক করলে এটি আমাদের অ্যাপ্লিকেশনের একটি নতুন উদাহরণ খুলবে, যা আমাদের নিম্নলিখিত বিভাগে মোকাবেলা করতে হবে।

using Microsoft.Win32;

public void Register()
{
    RegistryKey key = Registry.ClassesRoot.OpenSubKey("*\\shell\\"+KEY_NAME+"\\command");

    if (key == null)
    {
        key = Registry.ClassesRoot.CreateSubKey("*\\shell\\" + KEY_NAME + "\\command");
    }

    key.SetValue("", Application.ExecutablePath + " \"%1\"");
}

এই কোডটি রেজিস্ট্রি কী তৈরি করে যেখানে বর্তমানে চলমান অ্যাপ্লিকেশনটি অবস্থিত। "%1" স্বরলিপিটি নির্দেশ করতে ব্যবহৃত হয় যে শেলের মধ্যে নির্বাচিত ফাইলটি এই প্যারামিটারের ভিতরে পাস করা উচিত। KEY_NAME হল একটি সংজ্ঞায়িত স্ট্রিং ধ্রুবক যা প্রসঙ্গ মেনুতে এন্ট্রির পাঠ্য নির্ধারণ করে।

public void UnRegister()
{
    RegistryKey key = Registry.ClassesRoot.OpenSubKey("*\\shell\\"+KEY_NAME);

    if (key != null)
    {
        Registry.ClassesRoot.DeleteSubKeyTree("*\\shell\\"+KEY_NAME);
    }
}

এই পদ্ধতিটি আমাদের যোগ করা কাস্টম কীটি সরিয়ে দেয়, যদি এটি বিদ্যমান থাকে।

একাধিক দৃষ্টান্ত প্রতিরোধ

যেহেতু আমাদের অ্যাপ্লিকেশনটি সিস্টেম ট্রেতে থাকে, তাই আমরা চাই না যে প্রোগ্রামের একাধিক দৃষ্টান্ত একবারে চলুক। আমরা একটি Mutex ব্যবহার করতে পারি তা নিশ্চিত করতে যে শুধুমাত্র একটি দৃষ্টান্ত চলমান থাকে।

using System.Threading;

bool firstInstance;
Mutex mutex = new Mutex(true, "Local\\DocListUploader", out firstInstance);
if (!firstInstance)
{
  return;
}

উপরের কোডটি আমাদের অ্যাপ্লিকেশনের Main পদ্ধতিতে স্থাপন করা যেতে পারে যদি আমাদের প্রোগ্রামটি ইতিমধ্যেই চালু থাকে। যেহেতু Mutex "স্থানীয়" নামস্থানের মধ্যে রয়েছে, এটি আমাদের অ্যাপ্লিকেশনটিকে আলাদাভাবে চালানোর জন্য মেশিনে একটি ভিন্ন সেশনের অনুমতি দেয়। কিছু অতিরিক্ত যত্ন নেওয়া উচিত, তবে, যেহেতু আমরা বিশ্বব্যাপী রেজিস্ট্রি পরিবর্তন করছি।

আন্তঃপ্রক্রিয়া যোগাযোগ

যখন কোনও ব্যবহারকারী একটি ফাইলের জন্য শেল প্রসঙ্গ মেনু আইটেমটি ক্লিক করে যা আমরা আগে যুক্ত করেছি, তখন আমাদের অ্যাপ্লিকেশনটির একটি নতুন উদাহরণ চালু করা হয় এবং ফাইলটি ডিস্কে অবস্থিত যেখানে সম্পূর্ণ পথ দেওয়া হয়। এই তথ্যটি এখন অ্যাপ্লিকেশনটির ইতিমধ্যে চলমান উদাহরণের সাথে যোগাযোগ করতে হবে। এটি .NET ফ্রেমওয়ার্কের আইপিসি মেকানিজম ব্যবহার করে করা যেতে পারে যা 2.0 সংস্করণে চালু করা হয়েছিল।

using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;

আমরা যে বার্তাটি দিচ্ছি তা একটি কাস্টম অবজেক্টের রূপ নেয়। এখানে আমি এমন একটি অবজেক্ট তৈরি করেছি যা এই অ্যাপ্লিকেশনটির যুক্তিযুক্ত HiddenForm একটি রেফারেন্স ধারণ করেছে। যেহেতু এই বস্তুটি মূল দৃষ্টান্তে হোস্ট করা হবে, তাই এটি পরবর্তী উদাহরণে মূল উদাহরণের প্রধান ফর্মের সাথে যোগাযোগ করার একটি উপায় প্রদান করে।

class RemoteMessage : MarshalByRefObject
{
    private HiddenForm mainForm;

    public RemoteMessage(HiddenForm mainForm)
    {
        this.mainForm = mainForm;
    }

    public void SendMessage(string file)
    {
        mainForm.HandleUpload(file);
    }
}

যখন অ্যাপ্লিকেশনের প্রথম দৃষ্টান্তটি শুরু করা হয়, নিম্নলিখিত কোডটি এটিকে ধারাবাহিক দৃষ্টান্তের জন্য শুনতে সক্ষম করে:

public void ListenForSuccessor()
{
    IpcServerChannel serverChannel = new IpcServerChannel("DocListUploader");
    ChannelServices.RegisterChannel(serverChannel, false);

    RemoteMessage remoteMessage = new RemoteMessage(this);
    RemotingServices.Marshal(remoteMessage,"FirstInstance");
    
}

উপরে উল্লেখ্য যে এটি একটি নামযুক্ত IPC চ্যানেল নিবন্ধন করে, এবং আমাদের সংজ্ঞায়িত RemoteMessage অবজেক্টের একটি অনুলিপি প্রদান করে, এটিকে নিজেই একটি রেফারেন্স দিয়ে শুরু করে।

প্রোগ্রামের ধারাবাহিক দৃষ্টান্তের জন্য, args প্যারামিটারের মাধ্যমে Main এ প্রদত্ত স্ট্রিংটিকে মূল উদাহরণের সাথে পাস করতে হবে। শ্রবণকারী IPC চ্যানেলের সাথে সংযোগ করতে এবং মূল উদাহরণ থেকে RemoteMessage বস্তুটি পুনরুদ্ধার করতে নিম্নলিখিত কোডটি কল করা যেতে পারে। তারপরে SendMessage পদ্ধতিটি ফাইলের নামটি মূল উদাহরণে পাস করতে ব্যবহৃত হয়।

public static void NotifyPredecessor(string file)
{
    IpcClientChannel clientChannel = new IpcClientChannel();
    ChannelServices.RegisterChannel(clientChannel, false);

    RemoteMessage message = (RemoteMessage) Activator.GetObject(typeof(RemoteMessage), 
      "ipc://DocListUploader/FirstInstance");

    if (!message.Equals(null))
    {
        message.SendMessage(file);
    }
}

রিমোট মেসেজিং সিস্টেমটি খুবই শক্তিশালী কারণ এটির মাধ্যমে আমরা আমাদের প্রোগ্রামের একটি ইন্সট্যান্সের বিষয়গুলিকে স্থানীয় আইপিসি চ্যানেলের মাধ্যমে অন্য উদাহরণে দৃশ্যমান করতে পারি।

উপসংহার

এই নিবন্ধটি Google ডক্সের জন্য একটি বন্ধুত্বপূর্ণ মাইগ্রেশন ইউটিলিটি প্রদান করতে ডকলিস্ট আপলোডার নমুনায় ব্যবহৃত বিভিন্ন পদ্ধতি এবং কৌশলগুলির একটি উচ্চ স্তরে ব্যাখ্যা করে৷ এখনও প্রচুর কার্যকারিতা রয়েছে যা আপনার নিজস্ব অ্যাপ্লিকেশনগুলিতে যোগ করা যেতে পারে এবং আপনি আপনার নিজের উদ্দেশ্য অনুসারে নমুনাটি প্রসারিত করতে মুক্ত।

যারা ডকুমেন্ট লিস্ট ডেটা API এর সাথে কাজ করতে আগ্রহী, সেইসাথে যারা অন্যান্য Google Data API-এর সাথে .NET ব্যবহার করতে চান তাদের জন্য এখানে কিছু দরকারী সংস্থান রয়েছে: