Страницы

Поиск по вопросам

понедельник, 22 октября 2018 г.

Сохранение файла от имени пользователя C#

Вопрос: Можно ли сохранить файл в сетевую директорию используя учетную запись другого пользователя?
Подробности: Есть служба, работающая под учетно записью System. Служба, кроме прочего, занимается синхронизацией со сторонним сервисом из которого нужно выкачивать файлы и складывать в сетевую папку. Но у System нет прав доступа к сетевой папке. Зато служба знает логин/пароль пользователя, у которого такие права есть.
(Пока видится только сохранение файла в temp и запуск копирования через Process.Start, но может быть есть что-то более элегантное?)


Ответ

Вы можете выполнить код внутри своего процесса от другого пользователя. Сначала импортируем WinAPI функцию LogonUser
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool LogonUser( string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
А дальше вот так:
IntPtr token; if (LogonUser("SomeUser", "SomeDomain", "SomePwd", 2, 0, out token)) { var identity = new WindowsIdentity(token); using (identity.Impersonate()) { // здесь вы можете убедиться, что код выполняется под другим юзером Console.WriteLine(Environment.UserName); // делаем что-то File.WriteAllText(@"path.txt", "hello!"); } } else { Console.WriteLine("Invalid credentials"); }

Почему нельзя использовать StreamReader вместе с NetworkStream?

В книге Албахари "C# 6.0 in a Nutshell" написано следующее:
В действительности класс StreamReader абсолютно запрещено применять вместе с NetworkStream, даже если вы планируете вызывать только метод ReadLine. Причина в том, что класс StreamReader имеет буфер опережающего чтения, который может привести к чтению большего числа байтов, чем доступно в текущий момент, и бесконечному блокированию (или до возникновения тайм-аута сокета). Другие потоки, такие как FileStream, не страдают подобной несовместимостью с классом StreamReader, потому что они поддерживают определенный признак окончания, при достижении которого метод Read немедленно завершается, возвращая значение 0
Какая ошибка, например, в этом классе?
public class AsyncSocket : IDisposable { Socket socket; StreamReader sr;
public AsyncSocket() { socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sr = new StreamReader(new NetworkStream(socket)); }
// ... остальные члены убраны
public async Task ReadLineAsync() { return await sr.ReadLineAsync(); }
public void Dispose() { if (sr != null) sr.Close(); if (socket != null) socket.Dispose(); } }
Допустим, пришла строка "123
qwe". StreamReader считает всю её в свой внутренний буфер при вызове ReadLineAsync() вернет "123". Данные из внутреннего буфера не удаляются же? При втором вызове ReadLineAsync() завершится, когда придет конец строки и в результатом вернется "qwe". Албахари пишет про бесконечное блокирование, так к нему может привести и обычный метод Read, если никакие данные не будут отправлены сокету.
Объясните почему нельзя использовать класс StreamReader вместе с NetworkStream?


Ответ

"Буфер опережающего чтения" означает, что StreamReader попытается вычитать из потока сразу килобайт (bufferSize) данных. "Про запас". Это улучшает производительность в случае чтения с диска, но может приводить к непредсказуемым последствиям при чтении.
Особенность NetworkStream.Read в том, что он может блокироваться при чтении (в случае, если сокет еще открыт, но данных нет).
Албахари пишет о теоретической ситуации, когда
StreamReader мог бы вернуть вам данные (т.к. они есть в буфере), но обнаружил, что в буфере есть место и решил на всякий случай дочитать побольше данных в буфер вызвал NetworkStream.Read NetworkStream.Read заблокировался
И вы оказываетесь в ситуации, когда вроде как нужные вам данные пришли, но StreamReader висит и не возвращает ничего, т.к. хочет еще больше данных из потока.
На практике (в текущей реализации StreamReader и NetworkStream) такая ситуация не возникает, т.к.
StreamReader читает данные из входного потока только в случае, если в буфере недостаточно данных для завершения требуемой операции. NetworkStream.Read не блокируется, если хоть какие-то данные есть.
Т.е. блокировка произойдет только в случае, когда нужные данные действительно не пришли.
Но реализация — это одно, нет никаких гарантий что она не поменяется.
На самом деле проблема решается тем, что сочетание NetworkStream + StreamReader не имеет практической ценности. StreamReader приспособлен для работы с чисто текстовыми данными. Например, он пытается искать в читаемом потоке преамбулу (BOM), и вообще — использует сами данные для определения концов строк, что уже дико неудобно при работе с сетью.
По сети обычно передаются смешанные данные. Например, те же строки принято передавать в виде <длина><текст>, чтобы не попадать в ловушку "непонятно сколько данных вычитали и сколько еще ждать". Для такой работы со стримами удобнее использовать BinaryReader

Как сделать поисковый сниппет на Javascript?

Javascript. Есть массив со статьями. По ним происходит поиск через indexOf.
Как сделать сниппет аля гугл? То есть брать первое вхождение в строке и выдергивать несколько слов справа и слева?
Например ищем слово file в строке:
Edit config.toml and change the default properties to suit your own information. This is not required to run the example, but this is the global configuration file and you're going to need to use it eventually. Start here!
In a command prompt or terminal, navigate to the path that contains your config.toml file and run hugo. That's it! You should now have a public directory with a complete blog! Open public/index.html in your browser and bask.
If that wasn't amazing enough, from the same terminal, run hugo server. This will watch your directories for changes and rebuild the site immediately, and it will make these changes available at http://localhost:1313/ so you can view your finished site in your browser. Go on, try it. This is one of the best ways to preview your site while working on it.
И получить сниппет:
...global configuration file and you're...


Ответ

Можно так, как вариант:
var str = 'navigate to the path that contains your config.toml file and run hugo';
console.log(snippet(str, 'file'));
function snippet(stringToSearch, phrase) { var regExp = eval("/(\\S+\\s){0,3}\\S*" + phrase + "\\S*(\\s\\S+){0,3}/g") return stringToSearch.match(regExp); }

В чем различие Scanner, Console и BufferedReader?

Объясните, в чем различие для ввода данных в консоли Scanner, Console и BufferedReader bReader = new BufferedReader (new InputStreamReader(System.in)); и какой лучше из них использовать?


Ответ

Различие простое Scanner предназначен для разбора любого текста и, ввода с терминала, как частный случай. Он умеет выцеживать числа всякие и т.п. Удобен для простого разбора текстов и для всяких учебных задачек типа "введите число от нуля до трёх". Console нужен для вводы именно с консоли, но иногда это не работает: иногда нет консоли и тогда никак не воспользоваться этой штукой. Консоль не умеет ничего парсить, а только обеспечивать ввод, в том числе безопасный ввод пароля. BufferedReader нужен, чтобы буфферизовать чтение с любого потока. Как частный случай, можно буфферизовать ввод с терминала. Иногда используется ради метода readLine, когда сложно или просто день обрабатывать текст блоками. Для целей чтения текста из стандартного вводы или ручного ввода пользователя вполне пригодный вариант. Но при таком подходе придётся парсить числа вручную, что не слишком большая сложность. Сказать какой использовать вам никто не может. Это зависит от задачи и условий выполнения. Если данные поступают через стандартный ввод, то вероятно следует ожидаать, что Console вас подведёт. Scanner полезен, но он может оказаться слишком полезен и сильно всё затормозить, если данных очень много. Буфферизованный ввод тоже может подсунуть вам бяку, так что в любом случае следует рассматривать источник данных, объём данных и их характер, чтобы принять какое-то решение.

Запрет перетаскивания img и url браузером

Во многих браузерах (например в хроме и ие) возможно "перетащить" картинку или ссылку, зажав над ней левую кнопку мыши, допустим в адресную строку и т.д.. Требуется с помощью js запретить. Каким образом это возможно реализовать? (написан маленький скрипт, позволяющий зажав кнопку над элементов свободно перетаскивать его. Проблема в том, что если элемент - картинка, вместо перетаскивания, браузер (хром, ие и т.д. кроме опера) захватывает его по своему, для переноса в адресную строку, на панель и прочее. Надо как-то запретить браузеру его действие по умолчанию) p.s. -webkit-user-select: none; -moz-user-select: none; проблемы не решают


Ответ

el.onmousedown = function (e) { if (window.event.stopPropagation) window.event.stopPropagation(); window.event.cancelBubble = true; e.cancelBubble = true; } Поидее должно помочь

Стоит ли изучать Ruby или сразу начинать c Ruby on Rails [закрыт]

Всем привет! Дорогие друзья, стоит ли изучать Ruby или стоит сразу перейти к RoR, тяжело ли будет сразу начать с RoR?


Ответ

Обычно соваться использовать фреймворк без хорошего знания языка -- плохая затея, но в случае с Rails всё немного иначе. Дело в том, что в самом фреймворке очень часто используются DSL, и для их использования знание Ruby не сильно важно (лишь синтаксис). По-моему мнению, можно сразу начинать изучать Ruby on Rails даже если нет твёрдых знаний Ruby. Хотя конечно без них не обойтись в реальной разработке.

В чем разница вызовов(обьявлений) этих обьектов?

Добрый вечер, начал изучать js около месяц назад, начал с видеокурсов Специалист. В общем там обьекты обьявлялись и вызывались такими вот способами: 1) var iamobj=new Object; iamobj.name="giggity"; iamobj.show=function(){ alert(this.name); }
iamobj.show(); ну здесь понятно, обьявили обьект, обьявили свойство и метод, затем вызвали метод 2) function Test(name){ this.name=name; this.show=function(){ alert(this.name) } }
var iamobj=new Test("giggity"); iamobj.show(); что имеем здесь: снизу обьявили обьект и сразу-же присвоили ему функцию, куда передали значение, затем вызвали метод Здесь вроде бы как все понятно, не ясно только какой метод когда лучше использовать.. но затем начал вчитываться в статью про свойства и методы обьектов на javascript.ru и вообще запутался синтаксис совершенно другой.. сейчас покажу 3) var iamobj={ read:function(){ this.name=prompt("имя?") }, show:function(){ return this.name } }
iamobj.read(); alert(iamobj.show()) собственно.. вопрос.. что это вообще такое и зачем? внизу сразу вызывается метод у обьекта iamobj, потом поднимаемся вверх и только тут обьявляем обьект (var), считываем значения имени в методе.. и снизу вызываем еще один метод чтобы показать. между методами в обьекте обьязана стоять запятая.. зачем столько вариатов обьявлений? у каждого из них есть какое-то преимущество в определенном условии? 4) function show(){ this.name=name; alert(this.name); }
var iamobj=new show("giggity") снизу обьявили обьект, тут же вызвали ф-цию и передали в нее значение, та берет значение, присваивает и выводит.. легкий способ, но опять же, синтаксис другой 5) function iamobj(){ this.show=function(){ var a=prompt("name?") alert(a); } }
new iamobj().show(); опять же новый синтаксис, внизу обьявляем обьект и тут же пишем какой метод в нем хотим вызвать, обьект являетсо функцией(?), внутри которого каждое свойство = метод (так чтоли? зачем?) в общем, обьясните кто-то пожалуйста зачем столько вариантов разных есть и в чем преимущество каждого? хотя бы приблизительно, ато я что-то вообще уже теряюсь


Ответ

Столько возможностей объявления для нашего с вами удобства, правда что касается примера инициализации объекта с помощью ключевого слова new - это нечто иное, если быть точным то это одна из возможных реализаций ООП, раз уже задел этот вопрос - немного о концепции. Любая функция может вызываться при помощи оператора new, функция, далее конструктор, которая вызывается при помощи оператора new получает на вход переменную this которая является еще не созданным объектом (который она, собственно и вернет), в контексте ООП - экземпляром "класса". Не смотря на похожий синтаксис - ООП в javascript устроено не так как везде, если быть более точным - построено на прототипировании. Теперь непосредственно о прототипах - у любой функции есть прототип (если быть точным у любого объекта, но в нашем случае речь не об этом), прототип это объект к которому имеют доступ все экземпляры конструктора("класса") ( сам по себе он всего-лишь JavaScript объект ), в котором целесообразно хранить общие методы или свойства для всех экземпляров конструктора("класса"). Что же касается специфических свойств и методов - их необходимо (читай по хорошему) инициализировать в конструкторе. Важно добавить - prototype это 1 единственный объект, независимо от количества экземпляров, соответственно, если, например, писать так: var User = function( username ) { this.__username = username; this.getUsername = function(){ return this.__username; } this.setUsername = function( username ){ this.__username = username; } }
var user1 = new User('Vasya'); var user2 = new User('Petya'); В этом случае - методы getUsername и setUsername делают одну и ту-же работу, но, что касаемо памяти - это разные функции, в этом можно легко убедиться: alert( user1.getUsername === user2.getUsername ) // false alert( user1.setUsername === user2.setUsername ) // false Соответственно с точки зрения памяти и вообще здравого смысла - этот подход не лучшее решение. Но теперь о том как все это нужно делать в javascript'e, перепишем пример var User = function( username ) { this.__username = username; } User.prototype = { getUsername : function(){ return this.__username; }, setUsername : function( username ){ this.__username = username; } }
var user1 = new User('Vasya'); var user2 = new User('Petya');
alert( user1.getUsername === user2.getUsername ); // true alert( user1.setUsername === user2.setUsername ); // true Как мы видим - использовав прототип мы добились того что наши методы getUsername и setUsername не плодятся для каждого вызова конструктора, а инициализируются единожды, что уже совсем другое дело с точки зрения памяти и здравого смысла. Ну а что касаемо разницы между записями вида var obj;
obj = {}; obj.somePropName = someValue; // ........
obj = { somePropName : someValue, // ........ };
obj = new Object(); obj.somePropName = someValue; // ........ Отличия нет, по крайней мере с точки зрения производительности. Есть разница только с точки зрения работы геттеров и сеттеров в контексте глобального конструктора Object, но я не думаю что вам это принципиально. По поводу последнего примера, на самом деле, грубо, происходит следующее: function iamobj(){ this.show=function(){ var a = prompt("name?") alert(a); } }
// new iamobj().show(); var obj = new iamobj(); obj.show(); Точно так-же мы могли бы поступить, например, с DOM элементом: document.getElementById("someElementId").onclick = function(){ /* observer code here... */ } С точки зрения целесообразности - применимо только в том случае, если объект не будет использоваться далее, и даже не смотря на это Крокфорд (и я за компанию), все-же, советуют заранее объявлять переменные перед тем как с ними работать. Если вам нужен статический метод, то просто используйте объект без вызова функции в контексте конструктора с помощью new (что-то типа iamobj.show = function(){/*...*/}, iamobj.show()). Вообще надо понимать что и для чего используется, если отбросить new и все из него выплывающее - объект это всего-лишь хэш, то что в объекте могут храниться функции - особенность языка, то что функции хэша имеют доступ в теле функции к хэшу через перменную this - так-же особенности языка, благодаря им можно городить пространства имен и легко и без напряга писать singleton'ы (и многое другое), но, как-бы там не было - в своем элементарном проявлении это всего-лишь ассоциативный массив. Надеюсь этой информации достаточно, пожалуй прекращаю т.к. и так ответ "немного" растянулся.