{
    "version": "https:\/\/jsonfeed.org\/version\/1.1",
    "title": "IT science: заметки с тегом lazarus",
    "_rss_description": "IT science — статьи и инструкции из мира IT",
    "_rss_language": "ru",
    "_itunes_email": "",
    "_itunes_categories_xml": "",
    "_itunes_image": "",
    "_itunes_explicit": "",
    "home_page_url": "https:\/\/itscience.pro\/tags\/lazarus\/",
    "feed_url": "https:\/\/itscience.pro\/tags\/lazarus\/json\/",
    "icon": "https:\/\/itscience.pro\/pictures\/userpic\/userpic@2x.jpg?1658757154",
    "authors": [
        {
            "name": "IT science",
            "url": "https:\/\/itscience.pro\/",
            "avatar": "https:\/\/itscience.pro\/pictures\/userpic\/userpic@2x.jpg?1658757154"
        }
    ],
    "items": [
        {
            "id": "10",
            "url": "https:\/\/itscience.pro\/all\/rekursivnoe-udalenie-direktorii\/",
            "title": "рекурсивное удаление директории",
            "content_html": "<p>аналог<\/p>\n<blockquote>\n<p>rmdir \/s \/q <directory> или rm -rf <directory><\/p>\n<\/blockquote>\n<pre class=\"e2-text-code\"><code class=\"\">function DeleteDirectoryEx(DirectoryName: string): boolean;\n\/\/ адаптирована функция DeleteDirectory из модуля fileutil, спасибо Павлу Дмитруку\nvar\n  FileInfo: TSearchRec;\n  CurSrcDir: String;\n  CurFilename: String;\nbegin\n  Result:=false;\n  CurSrcDir:=CleanAndExpandDirectory(DirectoryName);\n  try\n         if FindFirstUTF8(CurSrcDir+GetAllFilesMask,faAnyFile,FileInfo)=0 then\n         begin\n           repeat\n             if (FileInfo.Name&lt;&gt;&#039;.&#039;) and (FileInfo.Name&lt;&gt;&#039;..&#039;) and (FileInfo.Name&lt;&gt;&#039;&#039;) then\n             begin\n               CurFilename:=CurSrcDir+FileInfo.Name;\n               if (FileInfo.Attr and faReadOnly)&gt;0 then\n                 FileSetAttrUTF8(CurFilename, FileInfo.Attr-faReadOnly);\n               if (FileInfo.Attr and faDirectory)&gt;0 then\n               begin\n                 if not DeleteDirectoryEx(CurFilename) then exit;\n               end\n               else\n               begin\n                 if not DeleteFileUTF8(CurFilename) then exit;\n               end;\n             end;\n           until FindNextUTF8(FileInfo)&lt;&gt;0;\n         end;\n         FindCloseUTF8(FileInfo);\n         if (not RemoveDirUTF8(DirectoryName)) then\n           begin\n             exit;\n             Result:=true;\n           end;\n  except\n    Result:=false;\n  end;\nend;<\/code><\/pre>",
            "date_published": "2019-04-12T09:06:18+03:00",
            "date_modified": "2019-04-16T14:47:25+03:00",
            "tags": [
                "free pascal",
                "lazarus"
            ],
            "_date_published_rfc2822": "Fri, 12 Apr 2019 09:06:18 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "10",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "highlight\/highlight.js",
                    "highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "9",
            "url": "https:\/\/itscience.pro\/all\/zapuskaem-vneshnee-prilozhenie-zhdem-zaversheniya-i-poluchaem-vy\/",
            "title": "запускаем внешнее приложение, ждем завершения и получаем вывод",
            "content_html": "<p>запускаем внешнее консольное приложение и ждем окончания его выполнения, после завершения получаем вывод в список<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">function RunScript(sCommand: String): TStringList;\nvar\n  OurCommand: String;\n  OutputLines: TStringList;\n  MemStream: TMemoryStream;\n  OurProcess: TProcess;\n  NumBytes: LongInt;\n  BytesRead: LongInt;\nconst\n  READ_BYTES = 204800;\nbegin\n  MemStream := TMemoryStream.Create;\n  BytesRead := 0;\n  OurProcess := TProcess.Create(nil);\n  OurCommand := sCommand;\n  OurProcess.CommandLine := OurCommand;\n  OurProcess.ShowWindow:=swoHIDE;\n  OurProcess.Options := [poUsePipes, poNoConsole];\n  OurProcess.Execute;\n  while OurProcess.Running do\n  begin\n    MemStream.SetSize(BytesRead + READ_BYTES);\n    NumBytes := OurProcess.Output.Read((MemStream.Memory + BytesRead)^, READ_BYTES);\n    if NumBytes &gt; 0\n    then begin\n      Inc(BytesRead, NumBytes);\n      Sleep(100);\n    end\n    else begin\n      Sleep(100);\n    end;\n  end;\n  Sleep(1000);\n  repeat\n    MemStream.SetSize(BytesRead + READ_BYTES);\n    NumBytes := OurProcess.Output.Read((MemStream.Memory + BytesRead)^, READ_BYTES);\n    if NumBytes &gt; 0\n    then begin\n      Inc(BytesRead, NumBytes);\n    end;\n    Sleep(100);\n  until NumBytes &lt;= 0;\n  MemStream.SetSize(BytesRead);\n  OutputLines := TStringList.Create;\n  OutputLines.LoadFromStream(MemStream);\n  result := OutputLines;\n  OurProcess.Free;\n  MemStream.Free;\nend;<\/code><\/pre>",
            "date_published": "2019-04-11T19:00:38+03:00",
            "date_modified": "2019-04-11T18:59:50+03:00",
            "tags": [
                "free pascal",
                "lazarus"
            ],
            "_date_published_rfc2822": "Thu, 11 Apr 2019 19:00:38 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "9",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "highlight\/highlight.js",
                    "highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "8",
            "url": "https:\/\/itscience.pro\/all\/poluchaem-soderzhimoe-url-podderzhivaetsya-http-https\/",
            "title": "получаем содержимое url (поддерживается http, https)",
            "content_html": "<p>Бывает в приложении для windows нужно по ссылке получить какую нибудь информацию, ниже представлена функция, которая это сделает быстро и без дополнительных библиотек<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">function get_from_server(const Url: string): string;\nconst\n  UserAgent = &#039;Mozilla\/5.0 (compatible)&#039;;\nvar\n  hInet: HINTERNET;\n  hURL: HINTERNET;\n  Buffer: array[0..1023] of AnsiChar;\n  BufferLen: cardinal;\nbegin\n  result := &#039;&#039;;\n  hInet := InternetOpen(PChar(UserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);\n  if hInet = nil then RaiseLastOSError;\n  try\n    hURL := InternetOpenUrl(hInet, PChar(URL), nil, 0, 0, 0);\n    if hURL = nil then RaiseLastOSError;\n    try\n      repeat\n        if not InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen) then\n          RaiseLastOSError;\n        result := result + UTF8Decode(Copy(Buffer, 1, BufferLen))\n      until BufferLen = 0;\n    finally\n      InternetCloseHandle(hURL);\n    end;\n  finally\n    InternetCloseHandle(hInet);\n  end;\nend;<\/code><\/pre>",
            "date_published": "2019-04-11T18:57:32+03:00",
            "date_modified": "2019-04-11T18:57:25+03:00",
            "tags": [
                "free pascal",
                "lazarus"
            ],
            "_date_published_rfc2822": "Thu, 11 Apr 2019 18:57:32 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "8",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "highlight\/highlight.js",
                    "highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "7",
            "url": "https:\/\/itscience.pro\/all\/poluchaem-namingcontexts-kontrollera-domena\/",
            "title": "получаем namingContexts контроллера домена",
            "content_html": "<p>Некоторую информацию можно получить от контроллера домена без авторизации, например, namingContexts.<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">function get_ldap_namingContexts(server: string): string;\nvar\n  ldap: TLDAPsend;\n  attr: TStringList;\nbegin\n  ldap:= TLDAPsend.Create;\n  attr := TStringList.Create;\n  attr.Add(&#039;namingContexts&#039;);\n  try\n       ldap.TargetHost := server;\n       ldap.TargetPort := &#039;389&#039;;\n         if ldap.Login then\n          begin\n           if ldap.Bind then\n            begin\n              ldap.SearchScope:=SS_BaseObject;\n              if ldap.Search(&#039;&#039;, False, &#039;(objectClass=*)&#039;, attr) then\n               begin\n                  result:= ldap.SearchResult.Items[0].Attributes.Get(&#039;namingContexts&#039;)\n               end;\n            end;\n           ldap.Logout;\n          end;\n  finally\n     ldap.Free;\n     attr.Free;\n  end;\nend;<\/code><\/pre><p>результатом работы этой функции будет: DC=domain,DC=loc<\/p>\n<p>про другие параметры можно почитать здесь: <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ms684291(v=vs.85).aspx\">https:\/\/msdn.microsoft.com\/en-us\/library\/ms684291(v=vs.85).aspx<\/a><\/p>\n",
            "date_published": "2019-04-11T18:53:24+03:00",
            "date_modified": "2019-04-11T18:53:19+03:00",
            "tags": [
                "free pascal",
                "lazarus",
                "ldapsend"
            ],
            "_date_published_rfc2822": "Thu, 11 Apr 2019 18:53:24 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "7",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "highlight\/highlight.js",
                    "highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "5",
            "url": "https:\/\/itscience.pro\/all\/ldapsend-poluchaem-sid-v-hex-formate\/",
            "title": "ldapsend, получаем sid в hex формате",
            "content_html": "<p>функция для тех, кто работает с LDAP (ActiveDirectory)<\/p>\n<p>Все знают, что sid LDAP возвращает в формате bin, сконвертируем в hex строку. Функция делает запрос к серверу и получает objectSid пользователя по sAMAccountName, затем конвертирует его в строку hex с разделителями запятыми. Результатом работы функции будет строка: 01,05,00,00,00,00,00,05,15,00,00,00,8a,1c,a9,8e,20,29,32,58,4f,d1,a7,56,50,04,00,00<\/p>\n<p>фильтр запроса (&(objectClass=user)(sAMAccountName=’+user_name+’)(!(userAccountControl:1.2.840.113556.1.4.803:=2))) исключает заблокированные учетные записи.<\/p>\n<p>не забудьте подключить модуль ldapsend из библиотеки Synapse <a href=\"http:\/\/synapse.ararat.cz\/doku.php\/\">http:\/\/synapse.ararat.cz\/doku.php\/<\/a><\/p>\n<pre class=\"e2-text-code\"><code class=\"\">function get_bin_sid_by_name(user_name,server,user,password,namingContexts: string): string;\nvar\n  ldap: TLDAPsend;\n  attr: TStringList;\n  s,str:string;\n  l:PAnsiChar;\n  l_l:integer;\nbegin\n  ldap:= TLDAPsend.Create;\n  attr := TStringList.Create;\n  attr.Add(&#039;cn&#039;);\n  attr.Add(&#039;sAMAccountName&#039;);\n  attr.Add(&#039;objectSid&#039;);\n  result:=&#039;&#039;;\n\n  try\n    ldap.TargetHost := server;\n    ldap.TargetPort := &#039;389&#039;;\n    ldap.UserName := user+&#039;@&#039;+copy(namingContexts,4,pos(&#039;,&#039;, namingContexts)-4);\n    ldap.Password := password;\n    ldap.SearchScope:=SS_WholeSubtree;\n    ldap.SearchSizeLimit:=0;\n    ldap.SearchTimeLimit:=0;\n\n\n    if ldap.Login then\n     begin\n       if ldap.Bind then\n        begin\n          if ldap.Search(&#039;CN=users,&#039;+namingContexts, False, &#039;(&amp;(objectClass=user)(sAMAccountName=&#039;+user_name+&#039;)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))&#039;, attr) then\n             begin\n               s:=ldap.SearchResult.Items[0].Attributes.Get(&#039;objectSid&#039;);\n               GetMem(l,length(s));\n               BinToHex((@s[1]),l,length(s));\n               result:=copy(l,1,length(s)*2);\n               str:=&#039;&#039;;\n               for l_l:=0 to length(s)*2 do\n                 begin\n                   if ((l_l mod 2 = 0) and (l_l&lt;&gt;0) and (l_l&lt;&gt;length(s)*2)) then\n                     begin\n                      str:=str+result[l_l]+&#039;,&#039;;\n                     end\n                   else\n                     begin\n                       str:=str+result[l_l];\n                     end;\n                 end;\n               result:=trim(str);\n             end;\n        end;\n     end;\n  finally\n     ldap.Free;\n     attr.Free;\n  end;\nend;<\/code><\/pre><p>user_name — sAMAccountName пользователя, чей sid хотим получить<br \/>\nserver — адрес сервера LDAP<br \/>\nuser — логин для авторизации<br \/>\npassword — пароль пользователя (достаточно прав обычного пользователя домена для чтения атрибутов)<br \/>\nnamingContexts — корень нашего домена, например dc=server,dc=loc<\/p>\n",
            "date_published": "2019-04-08T11:58:04+03:00",
            "date_modified": "2019-04-08T11:57:37+03:00",
            "tags": [
                "ActiveDirectory",
                "free pascal",
                "lazarus",
                "ldapsend"
            ],
            "_date_published_rfc2822": "Mon, 08 Apr 2019 11:58:04 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "5",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "highlight\/highlight.js",
                    "highlight\/highlight.css"
                ],
                "og_images": []
            }
        }
    ],
    "_e2_version": 4171,
    "_e2_ua_string": "Aegea 11.4 (v4171)"
}