Страницы

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

четверг, 21 февраля 2019 г.

Нужно ли делать проверку на Assigned перед вызовом Free или FreeAndNil?

Довольно часто в коде встречается вот такая конструкция:
MyObj: TObject;
..
if Assigned(MyObj) then FreeAndNil(MyObj);
или:
if Assigned(MyObj) then MyObj.Free;
Логика пишущего код скорее всего такая - "проверим указатель на валидность, перед тем как к нему обращаться".
Вопрос, нужна ли проверка if Assigned перед вызовом FreeAndNil или Free?


Ответ

Нет, такая проверка не нужна.
Процедура Assigned не проверяет валидность указателя, как многие иногда полагают, она лишь проверяет указатель на nil (справка).
Метод Free уже содержит проверку на nil в себе (проверяется по исходникам TObject.Free).
Процедура FreeAndNil присваивает указателю nil и так же вызывает Free, в котором присутствует эта проверка (также проверяется по исходникам SysUtils.FreeAndNil).

Что такое группа захвата в регулярных выражениях?

Что такое группа захвата в регулярных выражениях, зачем она нужна и как ее использовать?


Ответ

Группа захвата — это часть шаблона регулярного выражения, заключённого в круглые скобки; при совпадении шаблона с сопоставляемой строкой та часть строки, которая соответствует шаблону в скобках, будет помещена в результирующий массив в качестве отдельного элемента.

Пример 1
alert( 'Hello, World!'.match(/World!/) ); // World!
https://jsfiddle.net/6jypate5/
В примере выше выведется та часть строки, с которой совпал шаблон: World!

Пример 2
alert( 'Hello, World!'.match(/World(!)/) ); // World!,!
https://jsfiddle.net/pt7geaLx/
А в этом примере помимо части строки, с которой совпал шаблон: World!; выведется ещё и та часть строки, которая совпала с шаблоном в круглых скобках: !

Группу захвата ещё называют подмаской или подшаблоном (subpattern)... Их предназначение не только в том, чтобы помещать совпавшую часть строки в результат, но и в том, что к ним можно обращаться из других мест шаблона ...

Литература:
Learn.JavaScript.Ru Ru.WikiBooks.Org CyberForum.Ru PHP.Net

Способы тестрирования in-app покупок на реальных товарах

Я провел тесты на статических запросах, в ответ на которые Google возвращает не полную информацию о покупке, к примеру, нет цифровой подписи. Теперь я хочу протестить полный функционал, так как продукты в полной мере протестировать не получается, а подписки и промокоды вобще нельзя. И единственный способ это сделать, на сколько я понимаю, это купить продукт за реальные деньги, а потом делать его возврат? Или есть еще какие-то способы проверить работу приложения на реальных продуктах в Google Play ?


Ответ

Можно тестировать реальные покупки. В этом случае их цена будет указана как 0руб и, если это подписка, она будет иметь срок всегда 1 день. Необходимые условия для тестирования можно найти в официальном руководстве и кратко тут на русском

Возможно ли использовать вход mic-in, как audio-out в ноутбуке с Ubuntu

На ноутбуке Asus A72D аудио-выход не подлежит восстановлению. Возможно ли программно настроить микрофонный вход для использования наушников?
lspci определяет аудио-устройство как: Azalia (Intel HDA)
Если возможно, то, что для этого нужно?
(после поверхностного поиска, судя по тому, что удалось найти - аппаратно такая возможность существует)


Ответ

Вот, здесь нашлось решение: Using microphone input port as headphone output
Оказывается достаточно установить:
sudo apt-get install alsa-tools-gui
Открыть приложение:
hdajackretask
Выбрать свою аудио-карту, на Pink Mic, Rear side поставить галочку Override и выбрать Headphone. Нажать кнопку Install boot override и перезагрузиться. После этого у меня микрофонный вход заработал как аудио-выход.

Сложный декоративный заголовок с двумя отдельными границами

Какое решение Вы можете предложить для создания такого заголовка?

Как видите, левая полоска не явлется border-left, т. к. её длина (вернее, высота) не равна истинной высоте блока.
Я сам пробовал "нарисовать" левую полоску вручную, т. е. в виде отедльного блока со стилями и позиционированием, но мне такое решение не очень нравится, потому как совершенно лишено адаптивности (в мобильных версиях заголовки могут не уместиться в одну строку). Что-нибудь ещё возможно?


Ответ

В таких случаях традиционно пользуются псевдо-элементами ::before и ::after, потому что они позволяют экономить на мусоре в разметке.
Собственно, одну полоску рисуем бордером, другую — псевдо-элементом. По-моему, выбор произвольный. Я не заметил, чтобы это вызывало какие-то проблемы на узких экранах. (Или я неправильно понял ваше задание — у вас многострочный пример отсутствует.)
h1 { position: relative; padding: 3px 5px; border-left: 3px #666 solid; } h1::after { content: " "; display: block; position: absolute; left: -3px; right: 0; bottom: -5px; height: 2px; background: #888; }

Hello world!

Hello world!


Как правильно вызвать метод с CancellationToken на языке VB.NET

Имеется библиотека, в ней определены методы с непонятными для меня сущностями. Вот определения методов.
d__9))> Public Function GetAnswer(ImageFilePath As String, ct As CancellationToken) As Task(Of String) d__10))> Public Function GetAnswer(Img As Image, ct As CancellationToken) As Task(Of String)
Вопрос, как правильно вызвать метод GetAnswer и "с чем едят" CancellationToken
Dim retval As String = Await rucap.GetAnswer("", ??? )


Ответ

Вам нужно создать CancellationTokenSource, а в качестве аргумента передать значение свойства Token. Вызвав метод Cancel у source или задав ограничение по времени, вы сможете прервать выполнение операции.
Если прерывание операции вас не интересует, можете просто передать CancellationToken.None

Как вписать блок в блок без усечения ширины и скрыть часть блока за пределами родительского блока?

Есть код :


нужно выступающую часть блока Б скрыть за пределами блока А без усечения его ширины, вот таким образом:

что бы выступающей части видно не было.


Ответ

.a { overflow: hidden; } .b { position: relative; }
.a { height: 300px; width: 200px; background-color: red; position: inherit; overflow: hidden; } .b { height: 200px; width: 200px; background-color: blue; position: relative; top: 50px; left: 100px; }


Как сократить слишком длинное выражение в условии if?

if sea_player[x1 + 1][y1] != 'S' and sea_player[x1][y1 + 1] != 'S' and sea_player[x1 + 1][y1 + 1] != 'S' and sea_player[x1 - 1][y1 ] != 'S' and sea_player[x1][y1 - 1] != 'S' and sea_player[x1 - 1][y1 - 1] != 'S' and sea_player[x1 + 1][y1 - 1] != 'S' and sea_player[x1 - 1][y1 + 1] != 'S' and sea_player[x1 - 1][y1 - 1]:
можно ли сократить этот участок кода?
p.s. пишу морской бой на питоне с использованием коммандной строки. это условие проверяет,не граничит ли одноклеточный корабль при его установке с другими кораблями на поле(список из списков)


Ответ

Сам список смещений для соседних ячеек лучше генерировать, чем руками писать:
adjacent_vector = [(x,y) for x in range(-1,2) for y in range(-1,2) if not (x == 0 and y == 0)]
Тогда точно не пропустите или не продублируете какое-то направление. Кстати у вас дважды проверяется одна и та же ячейка sea_player[x1 - 1][y1 - 1] != 'S'
Список смещений можно один раз создать на все время работы программы.
Далее с помощью генератора и встроенной функции any можно проверить наличие 'S' в ячейках. Примерный код (не учитывает выход за границы вашего поля):
adjacent_vector = [(x,y) for x in range(-1,2) for y in range(-1,2) if not (x == 0 and y == 0)] adjacent_cells = (sea_player[x1 + a[0]][y1 + a[1]] == 'S' for a in adjacent_vector) if any(adjacent_cells): print 'found'
Функция any прекратит работу как только будет найдена первая ячейка с 'S', чтобы не тратить время на остальные ячейки (и генератор вместо списка здесь по той же причине).

Вопрос по поводу очередей в RabbitMQ

Здравствуйте. Я пытаюсь написать очередь на rabbitmq. На всех туториалах которых я смотрел, все работает следующим образом:
Есть код (отправитель), который посылает сообщение в очередь Rabbit'a и сразу завершается. Есть код (получатель), который работает постоянно слушая очередь, чтобы забрать с нее сообщение. После того того как ОН получит сообщение из очереди, есть возможность дать сообщение rabbit'у , что он его получил. И тогда rabbit удалит его из очереди. При этом сам получатель не знает доставлено ли сообщение или нет (оно просто удалилось из очереди).
Но мне этого не достаточно. Мне нужно, чтобы отправитель узнал, что сообщение доставлено.
То есть, попытаюсь привести пример.
Отправитель кладет в очередь два сообщения:
"привет" "пока"
Получатель получил сообщения, и отвечает :
"привет ок" "пока не ок"
Подскажите, можно это реализовать как-то?


Ответ

Вам нужно понять идеологию очередей, как они работают и в первую очередь -- "подтверждение сообщений" (acknowledgement, ack) как описано в этой статье
При выполнении задания - отправлять в другую очередь "задание id=123 выполнено" после успешного выполнения задания.
Плюс опционально:
держать очередь для нотификаций об ошибках периодически проверять "задания, которые зависли более чем на Х минут".
И ещё раз не могу не обратить ваше внимание на то, что у вас ДВЕ очереди сообщений: одна в RabbitMQ, другая - в MSSQL.
Синтетический пример. Допустим, у вас архив страничек в базе MSSQL. И тут же вы добавляете табличку, в которой ставите задания для ботов, которые качают новые статьи. Скачал - добавил новую запись в базу.
Вы сделали избыточную структуру. Можно было обойтись базой в MSSQL и хранить задания ТОЛЬКО в RabbitMQ. И держать сто подписчиков, добавлять и удалять их, чтобы качать быстрее. Обработчик взял задание, обработал, сохранил в базу, пошёл за следующим заданием. Взял другое, ан видит - статья пять минут назад обновлялась, это меньше чем заданный интервал свежести -- удалил из очереди.
Можно было бы не привлекать Rabbit MQ, оставить всё на базе MSSQL.
А у вас две очереди по факту. Такое ну бывает иногда приходится делать, если у вас MSSQL - в одной организации, а Rabbit MQ - это сторонний сервис. Или разные отделы, которые используют разные техологии (одни Linux, другие Windows), бывает и так. Но поскольку я не знаю ваших особенностей -- то просто указываю на излишнее дублировани, вероятно оно вам самому в глаза не бросается.

Долгий запуск android приложения

Очень долго запускается приложение (в этом примере 40 секунд) если запуск происходит впервые, потом запускается быстро.
Пробовал на простой активности (хотя есть и рабочие):
public class SplashActivity extends Activity {
private static final String TAG = "SplashActivity";
@Override public void onCreate(Bundle savedInstanceState) { Log.d(TAG, "onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); }
@Override public void onStart() { Log.d(TAG, "onStart"); super.onStart(); }
@Override public void onResume() { Log.d(TAG, "onResume"); super.onResume(); } }
Проект состоит из двух рабочих модулей.
Модуль app:
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.2.0' compile 'com.android.support:design:23.2.0' apt "org.androidannotations:androidannotations:$AAVersion" compile "org.androidannotations:androidannotations-api:$AAVersion" testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.2.0' compile 'com.github.ParkSangGwon:TedPermission:v1.0.8' compile 'com.vk:androidsdk:1.6.5' compile 'com.fasterxml.jackson.core:jackson-core:2.4.1' compile 'com.fasterxml.jackson.core:jackson-annotations:2.4.1' compile 'com.fasterxml.jackson.core:jackson-databind:2.4.1' compile project(':libw') }
Модуль libw:
dependencies { compile 'com.google.guava:guava:18.0' compile 'com.android.support:support-v4:22.1.1'
compile 'com.google.http-client:google-http-client:1.19.0' compile 'com.google.http-client:google-http-client-android:1.19.0' compile 'com.google.http-client:google-http-client-jackson2:1.19.0' compile 'com.google.oauth-client:google-oauth-client:1.19.0' compile 'com.google.code.gson:gson:2.4' compile 'com.google.code.findbugs:jsr305:3.0.0' compile 'com.google.protobuf:protobuf-java:2.6.1'
compile 'com.fasterxml.jackson.core:jackson-core:2.5.0' compile('com.crashlytics.sdk.android:crashlytics:2.5.7@aar') { transitive = true; } compile files('libs/m3u8parser-0.2.jar')
jaxDoclet("com.google.doclava:doclava:1.0.5") classpaths fileTree(dir: 'build/classes/release').matching { include 'io/x/sdk/S.java' } }
Лог:
07-04 17:18:37.893 31219-31219/com.sapp W/System: ClassLoader referenced unknown path: /data/app/com.sapp-1/lib/arm 07-04 17:19:17.429 31219-31219/com.sapp W/System: ClassLoader referenced unknown path: /data/app/com.sapp-1/lib/arm 07-04 17:19:17.488 31219-31219/com.sapp D/SplashActivity: onCreate 07-04 17:19:17.513 31219-31219/com.sapp D/SplashActivity: onStart 07-04 17:19:17.513 31219-31219/com.sapp D/SplashActivity: onResume 07-04 17:19:17.522 31219-31875/com.sapp D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: false 07-04 17:19:17.539 31219-31219/com.sapp D/SplashActivity: onStart 07-04 17:19:17.539 31219-31219/com.sapp D/SplashActivity: onResume 07-04 17:19:17.558 31219-31875/com.sapp D/libEGL: loaded /system/lib/egl/libEGL_mali.so 07-04 17:19:17.564 31219-31875/com.sapp D/libEGL: loaded /system/lib/egl/libGLESv1_CM_mali.so 07-04 17:19:17.602 31219-31875/com.sapp D/libEGL: loaded /system/lib/egl/libGLESv2_mali.so [ 07-04 17:19:17.641 31219:31875 E/ ] Device driver API match Device driver API version: 29 User space API version: 29 [ 07-04 17:19:17.641 31219:31875 E/ ] mali: REVISION=Linux-r3p2-01rel3 BUILD_DATE=Tue Jul 22 19:59:34 KST 2014 07-04 17:19:17.642 31219-31875/com.sapp I/OpenGLRenderer: Initialized EGL, version 1.4
В период долгого запуска приложения, в профайлере такая картина:
В период долгой загрузки приложения, на устройстве такая ситуация:
Это на экране можно видеть до появления в логе onResume, после чего отображается экран загрузки.
Тестировал на Api 21, 23.
Насколько я понимаю, долго происходит первоначальная инициализация, и связана она с загрузкой дополнительных библиотек. Как можно это ускорить или хотя бы отложить, чтобы показать экран загрузки?


Ответ

Это особенности работы виртуальной машины ART. На самом деле, долгая загрузка кажется долгой изза оптимизации приложения после его установки. То есть, дивайсу нужно время не на запуск приложения, а на его распаковку. Соответственно, пока приложение не распакуется, оно не сможет запуститься. Проверить мою теорию вы можете удалив приложение, установив APK файл, подождав ~40 сек, и запустив приложение.

Личные сообщения. Вывод диалогов

Есть 2 таблицы.
[users]
- id - name
[prmess]
- id - date - from_id - to_id - text - view (boolean) 1/0
Собственно с выводом данных конкретного диалога/добавлением сообщений и т.п. проблем нет. Возникает проблема с выводом списка диалогов. То есть сообщения от меня к пете, и от пети ко мне это один диалог, а как составить запрос таким образом? более того нужно как-то суммировать непрочитанные сообщения (view) в этом диалоге только от собеседника (исключая свои). На выходе должно получиться что то вроде:
Собеседник [Петя], непрочитанных сообщений [2], id собесед.=2 Собеседник [Вася], непрочитанных сообщений [5], id собесед.=3 Собеседник [Женя], непрочитанных сообщений [0], id собесед.=4 Собеседник [Коля], непрочитанных сообщений [1], id собесед.=5


Ответ

select name,sum(not_view) msg_cnt,int_id from ( select if(from_id=1,to_id,from_id) int_id, 1-view not_view from prmess where from_id=1 or to_id=1 ) A join users2 on id=int_id group by int_id

Как в php избавится от конструкции if isset()?

Чем можно заменить данную конструкцию?
В коде очень много подобных проверок, а выносить в отдельную функцию не очень хочется и данный массив берется после обработки xml файла.
if(isset($dict_notification->{'purchaseDocumentation'}->{'grantStartDate'})) { $date = $dict_notification->{'purchaseDocumentation'}->{'grantStartDate'}; } else { return; // old - $date = null; }


Ответ

либо вынести в отдельную функцию, массив по ссылке передавайте в нее - ничего страшного. Что-то в духе:
function turboset(&$array, $key, $default=''){ if (!isset($array[$key])){ return $default; } return $array[$key]; }
либо PHP7, пример оттуда
// Coalescing can be chained: this will return the first // defined value out of $_GET['user'], $_POST['user'], and // 'nobody'. $username = $_GET['user'] ?? $_POST['user'] ?? 'nobody'; ?>

MySql Handler. Обработка ошибок в процедурах

Как можно обработать ошибки при дублировании id.Например узнать в каком ряде (INSERT) она возникла, есть ли такой подход ?
Я вот который день пытаюсь его реализовать все не получается. IF, CASE че только не пробовал
DROP TABLE test; CREATE TABLE test(id INT,PRIMARY KEY (id));
DELIMITER | DROP PROCEDURE test | CREATE PROCEDURE test() BEGIN INSERT INTO test VALUES (1);
INSERT INTO test VALUES (1);
INSERT INTO test VALUES (1); END; | DELIMITER ;


Ответ

Тут приведен код который игнорирует дубликаты и записывает в переменную какое то сообщение при возникновении конкретной ошибки.
SELECT @myError покажет вам ее.
SELECT @x будет равен 3 поскольку были проигнорированы дубликаты и код дошел до конца.
На счет отловки в каком ряду возникла могу подсказать подход (Не пробовал). Можно в цикле запустить и инициировать какую нибудь переменную в ++ . А потом при ошибке конкатенировать с error сообщением,ну или что то в этом вроде.
DELIMITER | DROP PROCEDURE IF EXISTS test | CREATE PROCEDURE test() BEGIN DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @myError = 'You have a error '; SET @x=1; INSERT INTO test VALUES (1); SET @x=2; INSERT INTO test VALUES (1); SET @x=3; INSERT INTO test VALUES (1); END; | DELIMITER ;
CALL test();
SELECT @x; SELECT @myError;
Если надо сделать какое то действие при возникновении ошибок то пользуйтесь IF ... ELSE
DELIMITER | DROP PROCEDURE IF EXISTS test | CREATE PROCEDURE test() BEGIN DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2=1; SET @x=1; INSERT INTO test VALUES (1); SET @x=2; INSERT INTO test VALUES (2); SET @x=3; INSERT INTO test VALUES (3);
IF @x2 = 1 THEN SELECT 0 AS id,'Dannix net' AS title; ELSE SELECT * FROM tbl_name; END IF; END; | DELIMITER ;
CALL test(); SELECT @x; SELECT @x2;
Тут тоже почитайте полезная инфа DECLARE ... HANDLER Syntax

Хвостовая рекурсия JS

Доброго времени суток. Не могу понять, почему копятся стеки вызовов функций в хвостовой рекурсии, если результаты предыдущего вызова далее не используются. Например:
function foo(x, acc) { if (x < 2) { return acc; } return foo(x - 1, acc * x); } foo(100000, 1); // Maximum call stack size exceeded


Ответ

Стандарт содержит следующее упоминание
Tail Position calls are only defined in strict mode code because of a common non-standard language extension (see 9.2.7) that enables observation of the chain of caller contexts.

Хвостовые вызовы могут быть определены только в strict mode, из-за нестандартного расширения языка (см 9.2.7), которое позволяет следить за цепочкой вызываемых контекстов.
Таким образом в соответствии со стандартом, хвостая рекурсия в строгом режиме будет обработана правильно.
Поддерживаемость на данный момент оставляет желать лучшего

Ну и да, как уже упоминалось: в примере в вопросе не хвостовая рекурсия, для нее нужно добавить return, а так же указать strict mode, в итоге код должен принять следующий вид
function foo(x, acc) { 'use strict' if (x < 2) { return acc; } return foo(x - 1, acc * x); }

Можно ли считать синонимом объявления этих функций?

$str = 'Какая-то строка';
// Вариант со ссылкой use на переменную $str $foo = function ($sep) use ($str) { $out = $sep . $str . $sep; return $out; };
// Вариант с объявлением переменной $str глобальной $foo = function ($sep) { global $str; return $sep . $str . $sep; };
echo $foo('~');
Результат их работы идентичный. Я так понимаю, что оператор use передаёт в область видимости функции переменную $str. Оператор global внутри функции выполняет то же, что и use - значит эти два объявления можно считать синонимами?


Ответ

Вы используете анонимные функции, также известные как замыкания (closures), которые позволяют создавать функции, не имеющие определенных имен.
Замыкания могут также наследовать переменные из родительской области видимости. Любая подобная переменная должна быть объявлена в конструкции use. Изменения внутри не будут отражаться на переменной из родительской области видимости, чтобы изменять переменную внутри и отражать изменения в родительскую область необходимо добавить перед началом &, тогда переменная будет передана по ссылке.
$foo = function ($sep) use (&$str) { $out = $sep . $str . $sep; return $out; };
Конструкция global $a говорит о том, что переменная $а является глобальной, т. е. является синонимом глобальной $а и изменения внутри функции будут отражены в глобальную область видимости. После определения переменных через global все ссылки на любую из этих переменных будут указывать на их глобальную версию.
Таким образом иструкция global создает ссылку на массив $GLOBALS, т.о. эти две записи будут эквивалентны:
function test() { global $a; $а = 10; }
function test() { $а = &$GLOBALS['a']; $а = 10; }
Массив $GLOBALS доступен из любого места в программе — в том числе и из тела функции, и его не нужно никак дополнительно объявлять.
По вашему вопросу, могу сказать, то что вы определяете функции двумя способами является совершенно одинаковым. Вы просто меняете способ передачи параметров в функцию.
P.S. Чрезмерное определение глобальных переменных грозит усложнением поиска ошибок в программе. Это реальный способ довести до сумасшествия программиста, который будет потом разбирать твою программу.

Аналог явовского BigInteger

Есть ли в C++ аналог явовского java.math.BigInteger?


Ответ

В стандартной библиотеке С++ на текущий момент - нет.
boost::multiprecision содержит соответствующие аналоги. Там есть как арифметика расширенной фиксированной ширины, так и динамической ("бесконечной") ширины. Там есть как С++ оболочки для GMP (последнюю надо ставить отдельно), так и собственная независимая реализация.

Как настроить задачи для cron?

Есть такой таск: пользователь выбирает задачу и время ее выполнения(каждых 5 минут, каждый день и т.д).- это все я записываю в бд.
Есть файлик cron.php который выполняется каждых 5 минут проверяет в бд есть ли активные задачи.
Как правильно записывать в бд время, что бы php понимал стоит ли выполнить задачу или нет. Допустим пользователь выбрал каждых 5 минут - что записать в бд?
Подскажите кто с этим работал. Буду благодарен :-)


Ответ

Хранить в базе интервал в секундах и дату последнего запуска в unix timestamp. В бд добавляем в запрос: where (interval + laststart) < now() Получаем таким образом все задачи которые необходимо выполнить, и после выполнения записываем текущее time() в поле laststart.

Объясните в чем причина deadlock-а?

Нашел на хабре пример deadlock-а:
template class container { std::mutex _lock; std::vector _elements; public: void add(T element) { _lock.lock(); _elements.push_back(element); _lock.unlock(); } void addrange(int num, ...) { va_list arguments; va_start(arguments, num); for (int i = 0; i < num; i++) { _lock.lock(); add(va_arg(arguments, T)); _lock.unlock(); } va_end(arguments); } void dump() { _lock.lock(); for(auto e: _elements) std::cout << e << std::endl; _lock.unlock(); } };
void threadFunction(container &c) { c.addrange(3, rand(), rand(), rand()); }
int main() { srand((unsigned int)time(0)); container cntr; std::thread t1(threadFunction, std::ref(cntr)); std::thread t2(threadFunction, std::ref(cntr)); std::thread t3(threadFunction, std::ref(cntr)); t1.join(); t2.join(); t3.join(); cntr.dump(); return 0; }
Правильно ли я понимаю, что дедлок возникает из-за того что в одном и том же потоке вызывается addrange в котором сначала идет _lock.lock() а затем add в которой опять идет _lock.lock()? если да, то почему в следующем примере нету дедлока(слегка измененный в худшую сторону пример из книги Энтони Уильямса, где я специально unlock() не сделал):
struct Y { private: mutable std::mutex m; int data; int get_data() const { m.lock(); return data; }
public: Y(int&& data_) : data(std::move(data_)) {} friend bool operator==(Y const& lhs, Y const& rhs) { if(&lhs==&rhs) return true; auto lhs_ = lhs.get_data(); auto rhs_ = rhs.get_data(); return (lhs_==rhs_); } };
int main() { Y y1(1); Y y2(2); std::cout<<(y1==y2)<Тут тоже идет два раза подряд вызов get_data() где делается lock() без unlock(), однако программа не виснет, как в первом случае а все отрабатывает на ура


Ответ

По стандарту поведение для повторного вызова std::mutex::lock в одном потоке для одного и того же std::mutex не определено:
If lock is called by a thread that already owns the mutex, the behavior is undefined: for example, the program may deadlock.
В том числе, может возникнуть deadlock. В конкретной реализации, например в VS2015, в этом случае возникает исключение.
Ваш второй пример вызывает метод std::mutex::lock у разных объектов std::mutex, поэтому описанный выше эффект не возникает.

Как пофиксить проблему с hover в меню

Когда навожу курсор на элемент меню, появляется выпадающее меню. Когда пытаюсь навести на него, оно пропадает. Как пофиксить?


Ответ

Для этого выпадающее меню должно быть вложено в пункт меню. Все можно реализовать только на css. Пример:
li {cursor: pointer;} li.submenu ul {display: none; margin: 0px; padding-left: 30px;} li.submenu:hover ul {display: block;}

  • пункт меню 1
  • пункт меню 2
  • пункт меню 4

  • Интерполяция строк в C# 6 без использования $

    В конфигурационном JSON файле используются строки следующего вида:
    { "logFilePattern" : "{yyyy}.{mm}.{dd}.log" }
    Для замены используется множество разных текстовых заполнителей: вычисляемые пути файловой системы, которые зависят от пользователя и т.д.. Предполагается их замена и для этого в предыдущих версиях C# использовалось составное форматирование (могу ошибаться в термине) таким образом:
    string name = "Fred"; Console.WriteLine(String.Format("Name = {0}", name)); // output: "Name = Fred"
    С выходом C# 6 версии появилась возможность использовать именованные аргументы (могу ошибаться в термине) таким образом:
    string name = "Fred"; Console.WriteLine($"Name = {name}"); // output: "Name = Fred"
    Вопрос: как интерполировать строку с именованными аргументами сохраненую в переменной?
    string stringPattern = "Name = {name}"; string name = "Fred"; // ?
    Нашел здесь что это не возможно, т.к. код:
    string name = "Fred"; string name2 = $"Name = {name}";
    , компилятором приводится к:
    string name = "fred"; string name2 = String.Format("Name = {0}", name);
    Другим словами, это просто синтаксический сахар.


    Ответ

    UPD
    Если весь вопрос в том, как сгенерировать имя лог файла, то может проще обойтись таким способом? В конфигурации задаем валидный с т.з. .NET формат для даты:
    { "logFilePattern" : "yyyy.MM.dd.log" }
    Затем в коде выкусываем его и получаем имя файла:
    const string extension = ".log"; var datePattern = logFilePattern.Remove(logFilePattern.IndexOf(extension), extension.Length); DateTime date = DateTime.UtcNow; var logFileName = date.ToString(datePattern) + extension;

    О задаче в общем
    Наивная реализация может состоять просто в замене значения:
    string stringPattern = "Name = {name}"; string name = "Fred"; string formatted = stringPattern.Replace($"{{nameof(name)}}", name);
    Тут есть два недостатка:
    код неуниверсальный (хотелось бы иметь отдельный метод, типа FormatString(pattern, value1, value2, ...)) не учитывается возможное эскапирование фигурных скобок (строка "{{name}}" не является шаблоном, однако замена будет произведена) при наличии нескольких значений мы будем плодить лишние строки
    Метод вида FormatString(pattern, value1, value2, ...), насколько я понимаю, нереален, поскольку нет способа в вызываемом методе узнать имена параметров, с которыми он вызывался. Поэтому можно остановиться на, например, словаре:
    public static string FormatString(string pattern, IDictionary values)
    Эскапирование можно обработать регулярным выражением, но учитывая, что параметров может быть несколько, это тоже может быть излишне тяжелой операцией. Поэтому реализация в общем-то зависит от желаемой степени оптимизированности, в идеале надо вручную проходить char[]/List и менять его на ходу.
    На ночь глядя получилось так:
    public static string FormatString(string pattern, IDictionary values) { var buffer = pattern.ToList(); int replaceStartIndex = -1; int replaceEndIndex = -1;
    int index = 0; while (index < buffer.Count) { var character = buffer[index]; if (character == '{') { if (replaceStartIndex == -1) { replaceStartIndex = index; } else { replaceStartIndex = -1; } } else if (character == '}') { if (replaceEndIndex == -1) { replaceEndIndex = index; } else { replaceEndIndex = -1; } }
    if (replaceStartIndex > -1 && replaceEndIndex > -1) { var key = new string(buffer.Skip(replaceStartIndex + 1).Take(replaceEndIndex - replaceStartIndex - 1).ToArray()); var value = values[key]; var stringValue = value?.ToString(); buffer.RemoveRange(replaceStartIndex, replaceEndIndex - replaceStartIndex + 1); if (stringValue != null) { buffer.InsertRange(replaceStartIndex, stringValue.ToCharArray()); index = replaceStartIndex + stringValue.Length; } else { index = replaceStartIndex; } replaceStartIndex = -1; replaceEndIndex = -1; } else { index++; } }
    return string.Join("", buffer); }
    Проверка:
    static void Main(string[] args) { string stringPattern = "Name = {name}, Age = {age}, Null = {nullString}, Escape = {{escape}}"; string name = "Fred"; int age = 42; string nullString = null; string escape = "You shouldn't see this"; var values = new Dictionary() { [nameof(name)] = name, [nameof(age)] = age, [nameof(nullString)] = nullString, [nameof(escape)] = escape }; string formatted = FormatString(stringPattern, values); Console.WriteLine(formatted); }
    Вывод:
    Name = Fred, Age = 42, Null = , Escape = {{escape}}

    Как сделать такой ListView?

    Очень популярный шаблон, как его реализовать?


    Ответ

    Это называется Indexed ListView. Существует полно библиотек, например:
    https://github.com/rizafu/Android-Swipe-StickyHeader-PullToRefresh-Indexable-ListView https://github.com/ufo22940268/Android-CityIndexableListView
    Строка поиска над списком - это обычный SearchView

    Ошибка компиляции: Выражение должно представлять класс или структуру

    При компиляции выдаётся следующая ошибка:
    выражение слева от .print должно представлять класс, структуру или объединение.
    Код:
    class Object { private: char* name; char* teacher; short int hours; char* exam; float mark;
    public: Object::Object() { Object::name = "unknown"; Object::teacher = "unknown"; Object::hours = 0; Object::exam = "unknown"; Object::mark = 0; }
    Object::Object(char *n) { Object::name = n; Object::teacher = "Unknown"; Object::hours = 0; Object::exam = "unknown"; Object::mark = 0; }
    void Object::print() { std::cout << name << std::endl; std::cout << teacher << std::endl; std::cout << hours << std::endl; std::cout << exam << std::endl; std::cout << mark << std::endl; } };
    void main() { Object Program1(); Program1.print(); }


    Ответ

    Это канонический пример most vexing parse. Вы, согласно правилам языка, объявили не экземпляр класса, а прототип функции с пустым списком аргументов, возвращающей Object.
    Уберите лишние скобки после Program1
    Object Program1;

    Уточнение: чтобы не думать о случае отсутствия конструкторов, лучше писать так: Object Program1{}; (по причинам, сходным с этими), если ваша версия компилятора это позволяет.

    Один поток на action [закрыт]

    Читал на хабре статью про async/await и наткнулся на следующую строчку:
    Несмотря на то, что в ASP.NET нет выделенного UI потока, код в action-ах контроллеров не может выполняться более чем одним рабочим потоком одновременно.
    Исходя из этой строчки у меня возникают вопросы:
    Зачем так ограничивать action? Как это реализовано внутрях? lock в ActionInvoker'е?


    Ответ

    Вы просто не совсем правильно поняли мысль, котору пытался донести автор статьи. Он не пытался сказать, что один конкретный метод Action не может выполняться в нескольких потоках - ведь достаточно очевидно, что это не так.
    Если у вас пришел десяток одновременных HTTP-запросов на один и тот же Action - то это Action будет выполняться одновременно в 10 разных потоках. Никаких блокировок там нет.
    Автор статьи на хабре имел ввиду, что один конкретный запрос - один конкретный вызов Action для обработки конкретного запроса - будет выполняться одним конкретным рабочим потоком, к которому при этом будет привязан HttpContext этого самого запроса.

    Откуда взялся зазор между Toolbar и RelativeLayout внутри LinearLayout?

    Есть такая разметка:










    В предпросмотре видим зазор между тулбаром и RelativeLayout с EditText'ом:

    На устройстве зазор еще больше. Исследовал все что мог, без вашей помощи не обойтись.
    UPD
    А в следующем активити, там, где я не использую шторку или CoordinatorLayout, или виджет AppBarLayout все нормально:




    Ответ

    Для android.support.design.widget.AppBarLayout
    Используйте app:elevation="0dp"
    вместо android:elevation="0dp"

    Вывод в консоль Fortran 66 (IV)

    1) Дайте пример кода, чтобы вывести сообщение в консоль по спецификации Fortran 66, не сохраняя в переменных строку, а сразу оператор вывода со строкой. Пример на языке С#:
    Console.WriteLine("Программист Программисту Программист");
    2) Подскажите параметры чтения, чтобы не закрывал консоль, а ждал ввода любого символа обязательно Fortran66 он же FortranIV. пример на языке С#:
    Console.ReadKey();
    Спасибо. Работает!Но не забывайте, что там без наворотов доступно ток латиница А-Z
    program second
    WRITE(*,10) 10 FORMAT('Программист Программисту Программист') READ(*,20) 20 FORMAT(//) end program second


    Ответ

    Как-то так:
    WRITE(*,10) 10 FORMAT('Программист Программисту Программист')

    Вывод дочерних записей на страницу

    Всем добрый день, кто сталкивался с такой проблемой.
    Есть таблица Накладная, у нее есть дочерняя таблица товары в накладной. И есть таблица товаров.
    MVC 5 Можно было на страницы сделать следующею конструкцию:
    @foreach (var item in Model) { @Html.DisplayFor(modelItem => item.Name) @foreach (var items in item.ListProdukts) {
    @Html.DisplayFor(modelItem => items.Produkts.ProduktName) }
    Но в ASP.Net Core это не работает. При том что студия дает в подсказках кода все эти поля.
    Model:
    namespace Proba3.Models { public class Invoice { public int InvoiceId { get; set; } public string InvoiceName { get; set; } public ICollection ListProdukts { get; set; }
    } }
    namespace Proba3.Models { public class ListProdukt { public int ListProduktId { get; set; } public int ProduktId { get; set; } public virtual Produkt Produkts { get; set; }
    public int InvoiceId { get; set; } public virtual Invoice Invoices { get; set; } } }
    namespace Proba3.Models { public class Produkt { public int ProduktId { get; set; } public string ProduktName { get; set; } public ICollection ListProdukts { get; set; } } }
    Controllers:
    using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.EntityFrameworkCore; using Proba3.Data; using Proba3.Models;
    namespace Proba3.Controllers { public class InvoicesController : Controller {
    private readonly ApplicationDbContext _context;
    public InvoicesController(ApplicationDbContext context) { _context = context; }
    // GET: Invoices public async Task Index() { var applicationDbContext = _context.Invoice.Include(c => c.ListProdukts);
    return View(await applicationDbContext.ToListAsync()); }
    Views:
    @model IEnumerable
    @{ ViewData["Title"] = "Index"; }

    Index


    Create New

    @foreach (var item in Model) {
    @Html.DisplayNameFor(model => model.InvoiceName)
    @Html.DisplayFor(modelItem => item.InvoiceName) @foreach (var items in item.ListProdukts) {

    @Html.DisplayFor(modelItem => items.ProduktId)

    @Html.DisplayFor(modelItem => items.Produkts.ProduktName)

    }

    Почему не показывает ProduktName?


    Ответ

    Ответ дали на github.
    Оказывается ASP.NET Core теперь не добавляет дочерние элементы по умолчанию. Подробно можно прочесть на английском здесь: docs.asp.net
    В моем случае в Controller надо добавить:
    в строку:
    var applicationDbContext = _context.Invoice.Include(c => c.ListProdukts).ThenInclude(c => c.Produkts);
    вот это:
    .ThenInclude(c => c.Produkts);

    Работа с Github и Bitbucket с одного компьютера

    Имеется ноутбук с установленным git 2.9.3. Есть аккаунт на Github и Bitbucket, зарегистрированный на один и тот же e-mail.
    Могу ли я заливать одни проекты на Github, а другие Bitbucket? И нужны ли дополнительные настройки при заливке на Bitbucket?


    Ответ

    "Заливка" (Отправление файлов и изменений из локального репозитория в удалённый) осуществляется по адресу, который указан в remote каждого локального репозитория.
    Когда вы клонируете репозиторий с удалённого сервера (Github или Bitbucket) то в репозиторий устанавливается remote с именем origin в котором указан этот адрес. При git push origin файлы/изменения отправятся на удалённый репозиторий с указанным адресом.
    При этом ничто не ограничивает вас в смене и добавлении других remote-ов. Т.е. вы можете склонировать репу с Github, поменять remote и пушить на Bitbucket. Или наоборот. А можете добавить ещё один remote для к-л репы и пушить и в Github и в Bitbucket.

    Как открыть модальное окно Bootstrap без JQuery и bootstrap.js?

    В моем проекте не используется JQuery и bootstrap.js, так уж сложилось. Стараемся как можно меньше использовать библиотеки.
    Нужно реализовать модальное окно, но использовать вышеупомянутые JQuery и bootstrap.js ради одного окошка - крайне не желательно.
    Есть ли решение этой проблемы?


    Ответ

    Например самое простое с применением псевдокласса :target
    /* Стили для модального*/ #modal { display: none; } /* Изменяем вид вывода при соответствии */ #modal:target { display: block; } /* Закрытие модального*/ .close { position: absolute; top: 1rem; right: 1rem; } /* Доп. стилизация модального*/ #modal { max-width: 300px; height: 100px; margin: 2rem auto; border: 1px solid #ccc; padding: 5rem 2rem; text-align: center; position: relative; } /* Стилизация кнопки, чтобы глаз радовала.*/ .btn { width: 200px; height: 34px; line-height: 34px; border: 1px solid #ccc; border-radius: 25px; color: #111; background: #eee; text-decoration: none; display: block; text-align: center; position: relative; } вызвать модальное


    Псевдо класс :target является одной из замечательных особенностей CSS3. Он соответствует элементу, на который указывает идентификатор в URI документа. Идентификатор в URI содержит символ “#”, за которым следует имя идентификатора, соответствующее значению атрибута id элемента в документе.

    Округление после четырёх значащих цифр Python

    Имеется следующий результат вычислений:
    1.103567 -0.015367 0.000616 -0.023323 1.138369 -0.018582 -0.003442 0.004548 1.195153
    Устройство преобразует эти числа следующим образом:
    [1.104, -0.01537, 0.000616, -0.02332, 1.138, -0.01858, -0.003442, 0.004548, 1.195]
    Для дальнейшей работы необходимо сравнивать вычисления и числа внутри устройства, поэтому возникла потребность в округлении результатов вычислений так же, как это делается на устройстве. Round не даёт удовлетворительного результата.

    где m это DataFrame.


    Ответ

    Товарищ в комментариях подсказал еще один хороший способ, который при больших массивах данных гораздо более предпочтителен: Итак, у нас имеется результат вычислений m и данные с устройства newmatrix. Их необходимо сравнить.
    import numpy as np import pandas as pd
    m 0 1 2 0 1.099394 -0.015754 0.006890 1 -0.025979 1.119590 -0.002269 2 -0.021262 0.005393 1.191073
    type(m)
    newmatrix [1.099, -0.01575, 0.00689, -0.02598, 1.12, -0.002269, -0.02126, 0.005393, 1.191]
    type(newmatrix)
    Приводим newmatrix к формату DataFrame
    mat=np.array(newmatrix) mat=mat.reshape((3,3)) mat=pd.DataFrame(mat)
    mat 0 1 2 0 1.09900 -0.015750 0.006890 1 -0.02598 1.120000 -0.002269 2 -0.02126 0.005393 1.191000
    И затем одной функцией производим сравнение:
    numpy.allclose(m, mat, 1e-3,0) True

    Права пользователя вне роли

    Вопрос насчет permissions пользователя экземпляра sql сервера:
    Например есть у нас пользователь Vasiok, за ним закреплена роль sysadmin. Возможно ли ему закрепить permission вне зависимости от роли?? То-есть, я хочу чтобы он себе и далее был только sysadmin-ом, но кроме того у него еще был дополнительный permission.
    Если обобщить: могут ли существовать permissions отдельно от roles?


    Ответ

    могут ли существовать permissions отдельно от roles?
    Да, могут. И существуют.
    В SqlServer есть иерархия разрешений. Разрешения сами по себе не зависят от ролей. Напротив - роль содержит некоторый набор разрешений (и/или запрещений). Есть встроенные роли, - такие как, например, sysadmin, - набор разрешений для них фиксирован и не может изменяться (т.н. fixed roles). Начиная с SqlServer 2012 можно создавать собственные роли уровня сервера, собирая в них необходимые наборы разрешений.
    Логин может быть в какой-то одной роли, может быть в нескольких ролях одновременно, может не быть ни в одной роли(*), и также может иметь разрешения, установленные напрямую, а не через членство в ролях.
    Допустим есть логин
    USE [master] GO CREATE LOGIN [LoginName] WITH PASSWORD = N'L2RG9mZi6EZm' GO
    Можно сделать его членом роли сервера sysadmin
    ALTER SERVER ROLE [sysadmin] ADD MEMBER [LoginName] GO
    но можно дать широкие права и явно
    GRANT CONTROL SERVER TO [LoginName] GO
    Членство в роли sysadmin и право CONTROL SERVER эквивалентны(**)

    (*): строго говоря, любой логин всегда является членом специальной роли public, и отменить это нельзя. (**): на самом деле - почти (из-за некоторых legacy вещей).

    Получение длительности видео, Android

    Есть mp4 файл, как я могу получить длительность видеозаписи?


    Ответ

    Получить длительность видео можно как:
    MediaPlayer mp = MediaPlayer.create(this, Uri.parse(uriOfFile)); int duration = mp.getDuration();
    Источник

    Подскажите, как лучше оформить класс

    В общем, хочу сделать класс, который будет импортировать DataTable в Access или MS SQL.
    Класс будет иметь 1 метод: Append, которому на вход будет подаваться DataTable, а метод в свою очередь будет загружать DataTable в нужный пункт назначения.
    Разумеется, внутренняя логика Append у Access может сильно отличаться, например:
    В Access нужно следить за тем, что бы файл не был выше 2гб, иначе бд поломается В MS SQL можно воспользоваться BulkCopy, а в Access потребуется какой-то самопал.
    Соответственно и конструкторы могут сильно отличаться по параметрам, например:
    Строки подключения между двумя типами будут отличаться В MS SQL можно использовать или не использовать транзакцию В Access можно восстанавливать или не восстанавливать БД после каждого Append.
    Как лучше всего все это оформить?
    UPD:
    Есть у меня некоторые предположения, как это можно сделать, но не знаю на сколько это верно.
    Сделать интерфейс:
    public interface IApend { void Append(DataTable dt); }
    Реализовать его в 2 ух классах, каждый из которых будет содержать в себе собственную логику импорта:
    public class ImporterToSQL: IApend { //Какие-то поля public void Append(DataTable dt) { //Какая-то логика } } public class ImporterAccess : IApend { //Какие-то поля public void Append(DataTable dt) { //Какая-то логика } }
    И создать такой класс:
    public class Importer { IApend Concrete;
    public Importer(IApend concrete) { Concrete = concrete; } static Importer ImporterToSQL(object v,object v2,object v3) { return new Importer(new ImporterToSQL(object v, object v2, object v3)); } static Importer ImporterToSQL(object v, object v2) { return new Importer(new ImporterToSQL(object v, object v2)); } static Importer ImporterToAccess(object v, object v2, object v3) { return new Importer(new ImporterAccess(object v, object v2, object v3))); } static Importer ImporterToAccess(object v, object v2) { return new Importer(new ImporterAccess(object v, object v2)); } public void Append(DataTable dt) { Concrete.Append(dt); } }
    На сколько это верно и на сколько хорошо этот подход будет работать в плане добавления нового функционала(Например, мне приспичило добавить импорт из SQL в Access)? Это , вроде, зовется фабрикой классов?


    Ответ

    Вы на правильном пути. Общий интерфейс для конвертации -- это правильно. Только я бы назвал его чуть поконкретнее, хотя б IImporter какой-нибудь.
    Что касается создания конкретных экземпляров и вашего класса Importer. Для создания действительно нужна фабрика. Однако она у вас получилась не в чистом виде. Смысла оборачивать экземпляр в ваш Importer нет -- у вас уже есть интерфейс. Просто создавайте нужные экземпляры и возвращайте их. А клиент уже будет вызывать напрямую методы:
    public static class ImporterFactory { static IImporter CreateSQLImporter(object v, object v2, object v3) { return new ImporterToSQL(v, v2, v3); }
    static IImporter CreateAccessImporter(object v, object v2, object v3) { return new ImporterAccess(v, v2, v3); }
    // и так далее }
    В качестве параметров для конструкторов у вас наверняка выступают специфичные для каждой реализации данные: например, строка подключения для SQL и путь к mdb файлу для Access. В идеале клиент вообще не должен знать что-то о деталях реализации, а фабрика должна содержать один метод на тип. Все детали о реализации прячутся в фабрике, которая подсовывает нужные параметры напрямую из конфигурации (например, из app.config). При этом клиент вообще ничего не будет знать о реализации:
    public static class ImporterFactory { static IImporter CreateImporter(object v) { var generalConfig = GetGeneralConfig(); if (generalConfig.Type == "sql") { var config = GetSqlImporterConfig(); return new ImporterToSQL(config.ConnectionString, v); } else if (generalConfig.Type == "access") { var config = GetAccessImporterConfig(); return new ImporterToAccess(config.ConnectionString, v); } } }
    Такой подход будет очень хорошо работать, если вам потребуется импорт в новое место. Вы просто напишете еще одну реализацию IImporter, внести изменения в ImporterFactory и все. Все клиентs, которые используют IImporter, менять не придется. В случае же отдельных методов вам придется менять вызывающий код, который управляет тем, какой метод вызвать.

    Что касается импорта из SQL в Access, то такую задачу описанным выше способом не решить. Выше мы рассмотрели только задачу "как данные, представленные в универсальном виде (DataTable), записать в конкретное место". Задачу импорта из SQL в Access можно переформулировать как "как извлечь данные из одного места и записать их в другое место". Такую задачу полезно разбить на два шага и ввести промежуточный этап. Какой? Правильно, получение данных в универсальном виде. Таким образом, шага будет два:
    Импорт из источника с преобразованием в универсальный вид Экспорт в другое место
    Соответственно, два основных контракта будут выглядеть как-то так:
    interface IImporter { DataTable Import(); }
    interface IExporter { void Export(DataTable data); }
    Реализация второго шага у вас уже есть, правда сейчас она называется импортом. При наличии двух шагов будет логичнее назвать их с т.з. того, как данные движутся относительно вашего приложения. Вы импортируете (загружаете) данные из одного источника и экспортируете (выгружаете) их в другое место.
    Реализация первого шага будет аналогична -- различные реализации интерфейсов, фабрика.
    Для осуществления процесса конвертации вам понадобится некоторая общая сущность, которая будет соединять шаги. Она может принимать в качестве зависимостей как фабрики, так и экземпляры импортера/экспортера:
    public class DataConverter // придумайте имя поудачнее, пожалуйста :) { private readonly IImporter _importer; private readonly IExporter _exporter;
    public DataConverter(IImporter importer, IExporter exporter) { _importer = importer; _exporter = exporter; }
    public void Convert() { var data = _importer.Import(); _exporter.Export(data); } }

    Сборка проекта С++/С# из командной строки

    Требуется собрать проект с помощью bat-файла. Параметры сборки следующие:
    MsVstudio\incredibuilder - тип сборки локальная\распределенная win32\x64 debug
    elease build
    ebuild
    Можно ли как-то при запуске VS передать в неё такие параметры? Читал про команду devenv, она даёт возможность только указать Build или Rebuild.


    Ответ

    В общем локальная сборка делается с помощью MSBuild, как мне посоветовали выше.
    Полный пример:
    msbuild.exe %SolutionPath% /t:build /p:configuration=release /p:platform=x86
    Запускается из Bat, только после перехода в каталог, в котором находится MSBuild.
    Распределённая сборка, через IncrediBuild, делается через BuildConsole:
    BuildConsole.exe %SolutionPath% /build /cfg="release|x86"
    Является командой самой windows cmd, так что ничего придумывать не надо.