вторник, 30 ноября 2010 г.

Visual Studio С# 2010 Express. Не сохраняются данные в базе.

 Я потерял часа три на то, что бы понять, почему, когда я вызываю функцию DataContext.SubmitChanges(), данные в базе данных не обновляются. При этом никаких ошибок нет. Если в точно такую же ситуацию попали и вы, советую почитать вот здесь:
http://www.visualstudiodev.com/visual-c-express-edition/tableadapter-not-inserting-rows-to-the-database-43671.shtml
Если коротко, то при отладке программы в Visual Studio C# Express, файл базы данных копируется в каталог "(ProjectDir)\bin\Debug\mydatabase.mdb" и все изменения происходят уже в этой базе. Их не увидишь, пока не сделаешь еще одно подключение в проекте на этот файл базы данных. Ну а если эти данные важны для вас, то придется вручную заменить оригинальный файл базы данных на файл временной  базы. До этого я использовал Visual Studio Web Developer 2008 Express, ничего такого там не было.

суббота, 13 ноября 2010 г.

Осваиваем LINQ to XML

Как я описал в предыдущем посте Разбор HTML в Microsoft C Sharp запрос по URL  http://sberbank-ast.ru/PurchaseList.aspx возвращает данные  в XML формате. Нам нужно их разобрать. Как раз есть повод применить LINQ to XML. Сразу посоветую книжку для изучения. Авторы: Джозеф Албахари, Бен Албахари. Название - "LINQ карманный справочник". Очень доходчиво написано.
В этой книжке также есть ссылка на программу LINQPAD, где можно поупражняться в написании запросов на LINQ. Программа бесплатная, но за такой сервис, как "autocompletion" (аналог intellisense в Visual Studio) придется заплатить. Итак имеем XML структуру :

Допустим нам нужно найти purchID по определенному фильтру. Вот как выглядит код:


То есть мы выводим идентификаторы тех аукционов, которые в своем наименовании содержат слово "Поставка", и их ID больше 58061, и в описании встречаются или "Саратов" или "Москва".
Есть один момент, который меня не устраивает в этом коде. Хотелось бы, чтобы фильтр был универсальным. Например, я хочу включить несколько городов.  Понятно, что здесь нужно использовать деревья-выражения. Вот здесь мне и помог  Джозеф Албахари. Он написал универсальные extension функции для типа Expression < Func <T,TResult>>. По этой ссылки вы найдете их определения и примеры использования.
Dynamically Composing Expression Predicates
А теперь как изменился код:




Обратите внимание на Compile(). Мне пришлось использовать эту функцию для того что перевести дерево-выражение в лямбда-выражение , так как запрос локальный и возвращает тип IEnumerable, а не интерпретируемый, который возвращает IQueryable. Разница между двумя типами  описана в книге "LINQ карманный справочник".

среда, 10 ноября 2010 г.

Разбор HTML в Microsoft C Sharp

Приятно когда опытные программисты делятся полезными идеями и даже кодом своих программ. Вот один из примеров. Для своего нового проекта мне понадобился разборщик HTML. Мне нужен очень простенький, где я мог бы для определенного атрибута вытащить его значение. В принципе в сети нашел несколько вариантов. Но остановился вот на этом:
Parsing HTML in Microsoft C#.
Очень советую. Все просто и нагладно показано.   Вот пример как я его использую. Мне нужно получить реестров аукционов с сайта http://sberbank-ast.ru/PurchaseList.aspx  Посмотрев HTML -код страницы нашел тег input c атрибутом name="ctl00$ctl00$phWorkZone$xmlData"  - это для меня ключ поиска, но а потом у этого же тега вытаскиваю значение атрибута value со списком новых аукционов < input name="ctl00$ctl00$phWorkZone$xmlData" text="text" value="..здесь данные которые мне нужны...      Вот код для получения этих данных:



tag ["value"].Value не совсем еще XML. Просто вместо "<" стоит &lt  поэтому и понадобилась процедура для замены. Вот код этой процедуры



Вывод программы примерно следующий:

среда, 22 сентября 2010 г.

Настройка URLScan

Почитав некоторые материалы в сети ( например: http://www.hanselman.com/blog/HackedAndIDidntLikeItURLScanIsStepZero.aspx
http://haacked.com/archive/2008/08/22/dealing-with-denial-of-service-attacks.aspx), я пришел к выводу, что к моему написанному приложению ASP.NET нужно срочно приделать URLscan.
Итак, качаем отсюда http://www.iis.net/download/urlscan . Устанавливаем на сервере. В каталоге c:\windows\system32\inetsrv\ появляется новая папка urlscan.
В ней два файла urlscan.dll и urlscan.ini. Эти файлы отвечают за глобальную фильтрацию всех сайтов, расположенных на сервере. Но можно настроить и отдельно для каждого сайта. Для этого нужно скопировать эти два файла в корневой каталог. Например, у меня корневой каталог моей программы (сайта) c:\Inetpub\foo.  Так как у меня права NTFS на корневой каталог только "чтение", на файл urlscan.dll пришлось дать права "чтение и выполнение" пользователю IIS_WPG. Теперь идем в "Диспетчер служб IIS" . Правой клавишей мыши достаем свойства сайта и в закладке "фильтр ISAPI" добавляем urlscan из корневой директории.
По умолчанию urlscan.ini уже содержит настройки фильтрации. Но я хотел все-таки несколько увеличить безопасность. Для начала  нужно настроить лог. В urlscan.ini  существует параметр для указания пути к лог файлу "LoggingDirectory". Я указал c:\InetPub\foo\logs. После этого не забудьте  дать NTFS права на "запись" IIS_WPG и IIS права на "запись" на этот каталог.
 Потом прошелся по настройкам в urlscan.ini. Во первых, я включил (то есть установил в единицу) параметр UseAllowExtensions=1. Это значит будет отрабатывать секция [AllowExtensions] , если параметр 0 - то отрабатывет [DenyExtensions].  У меня она выглядит так
[AllowExtensions]
.
.css
Это список разрешенных раcширений. У меня получился вот такой маленький.
 "." точка нужна для файлов без раcширений. Без этой точки у меня приложение не запускалось.
Затем я переключился на параметры в секции [RequestLimits]
MaxAllowedContentLength=30000000
MaxUrl=260
MaxQueryString=2048
Это явно излишне для моего сайта. Немного теории . Как вы знаете, протокол HTTP использует два метода запроса к серверу GET и POST. Они отличается тем,что при методе GET запрос как бы является частью URI. Например http://www.google.ru/search?source=ig&hl=ru&rlz=1R2GFRE_ruRU333&q=urlscan&aq=f&aqi=g10&aql=&oq=&gs_rfai=
 и тело запроса пусто . А при методе POST данные передаются в теле запроса.  Так вот параметр "MaxAllowedContentLength" как раз относится к POST, а  "MaxQueryString" - GET. MaxUrl - это максимальное количество символов в строке URL без QUERY_STRING. Опытным путем я вычислил следующие значения
MaxAllowedContentLength=30
MaxUrl=30
MaxQueryString=60

пятница, 18 июня 2010 г.

Проблемы локализации меню DotNetNuke 5.x.x

Сразу скажу эту проблему я так и не решил . Просто не сложилась мозаика из DotNetNuke 5 , меню, и шаблона(skin). Теперь все по порядку.

Так как у меня уже есть один сайт на DotNetNuke 4.5, я смело принялся создавать страницы с названиями на русском языке. Но стоп, они не открываются . Они даже потом не редактируются. Их можно только удалить. Я не придал этому большого значения, отложил это на потом  и принялся искать по интернету бесплатные скины и модули. Мне нужен был модуль фото галерея . Я нашел даже два . Вот ссылки:
Photo Gallery - http://oliverhine.com/DotNetNuke/Modules/PhotoGallery.aspx
WnsLightbox Gallery -http://wnslightbox.codeplex.com/
Подобрал себе скин вот отсюда:
http://www.dnnskins.com/

Перехожу к руссификации меню.

Итак, 1 вариант, который я испытал - DSlocalizator http://dnn.tiendaboliviana.com/
На сайте выложена версия 03.00.04 бета. Сколько я не пытался ничего не получилось . А  на DotnetNuke 4 DSLocalizator работает на ура.

2 вариант - EALO  http://ealo.codeplex.com/releases/view/33940
Качаем EALO CoreAPI и EALO Tab localization. Почитайте Readme на сайте, потому что в дистрибутивах его нет. В принципе все понятно . После установки , просто добавьте модуль EAOL tab на какую нибудь страницу и укажите русский вариант всех своих страниц. Я смог руссифицировать стандарное меню , но вот меню моего скина нет. Нет в моем скине dnn:nav ..., а есть dnn:menu.. и, как я понял из форума, EALO мне не поможет http://www.dotnetnuke.com/Community/Forums/tabid/795/forumid/77/threadid/350801/scope/posts/Default.aspx

3 вариант - DNN menu http://www.dnngarden.com/ . Для руссификации должен быть установлен EALO.  Попытка была для меня тоже неудачной. Руссифицировать получилось, но модуль работал нестабильно, в какой-то момент, почему-то слетал style тага td, в котором был пункт меню, и он становился черным. Возможно все мои проблемы были из-за выбранного мною скина.

В итоге, я установил DotNetnuke 4.9.5 и DSLocalizator. Но, к сожалению, модули фото галерей были только под пятерку. Пришлось искать . Фришных нет вообще.
Вот удалось отсюда скачать
http://www.labellarte.it/DotNetNuke/DnnThickGallery12/tabid/438/Default.aspx

Установка DotNetNuke 5.4.1

У меня уже есть опыт разворачивания сайта DotNetnuke только ранней четверки. Теперь решил взяться за пятерку. Вот некоторые нюансы установки.У вас уже должен быть установлен SQL Express, IIS и Net Framework как минимум 2.

1. Заходим по ссылке качаем дистрибутив
http://www.dotnetnuke.com/tabid/125/default.aspx

2. Полученный архив распаковываем в c:\DotNetNuke

3. Находим файл readme.txt в c:\DotNetNuke\documentation и
выполняем требования описанные в этом файле.
 На каталог c:\DotNetNuke даем полные права ASP_NET юзеру, если конечно у вас XP.
 Создаем базу данных DotNetNuke в SQLExpress и пользователя, например dnnuser, с правами "db_owner".
Редактируем connectionstring в web.config .
Заходим в IIS создаем виртуальный каталог DotNetNuke, указывающий на  c:\DotNetNuke. Файл default.aspx должен быть документом по умолчанию.

4. Запускаем IE . Вводим в строке localhost/dotnetnuke.
Тут же у меня вылетела ошибка. Оказывается, если IIS был установлен после Net Framework, необходимо выполнить c:\Windows\Microsoft.Net\Framework\v2.0.50727\aspnet_regiis.exe

5.  Дальше проходим программа установки запрашивает информацию. Коротко несколько нюансов.
При выборе установки по умолчанию устанавливается только один модуль "Text/HTML".

Выполнение скриптов может завершиться с ошибкой. Хотя это и не указано в Readme.txt, но необходимо дать права на запись на каталог c:\windows\temp учетной записи ASP_NET.

После установки сразу же качаем устнавливаем language pack
http://www.dotnetnuke.com/Development/LanguagePacks/tabid/933/Default.aspx
Кстати, он в пятерке устанавливается как обычный модуль.

понедельник, 24 мая 2010 г.

WebException Сервер нарушил протокол. Section=ResponseHeader Detail=Недопустимое имя заголовка

В моем проекте MVC мне понадобилось подключиться к принтерам через WEB интерфейс. Я хотел программно считать пробег.
Получилось вот что:

Dim wc As New System.Net.WebClient
Dim Stream As System.IO.Stream
Try
 Stream = wc.OpenRead("http://" & Specific.IP_add _  

  "/hp/device/this.LCDispatcher?dispatch=html&cat=0&pos=1")
 Using sr As New System.IO.StreamReader(Stream)
  str = sr.ReadToEnd()
  Stream.Close()
 End Using
 Return CType(CountStr, Integer)
Catch ex As Exception
 Dim errorstring = ex.Message
End Try


У принтера HP4350 без проблем считалась страница, а вот у HP 4300 никак.
Ошибка была следующая :
"Сервер нарушил протокол. Section=ResponseHeader Detail=Недопустимое имя заголовка"
Решение удалось найти. Необходимо в файле web.config внести следующие изменения:

<configuration>
   <system.net>
       <settings>
          <httpwebrequest useunsafeheaderparsing="true">
       <settings>
   <system.net>
<configuration>

С принтером 4515 тоже не очень гладко получилось , так как  WEB интерфейс был доступен по протоколу https. Возникало следующее исключение:
"Базовое соединение закрыто Не удалось установить доверительные отношения для защищенного канала SSL TLS". Вот по этой ссылке сделал.
http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/c98ea134-c582-4c2a-8c42-d7e31f7fe389
Итак определяем функцию, котрая возвращает всегда "True"

Private Function ValidateCertificate(ByVal sender As Object, _
  ByVal certificate As  X509Certificate, ByVal chain As X509Chain, _
  ByVal sslPolicyErrors As SslPolicyErrors) As Boolean
  Return True
End Function


А вот ее вызов

Dim wc As New System.Net.WebClient
Dim Stream As System.IO.Stream
Try
 System.Net.ServicePointManager.ServerCertificateValidationCallback = _

 New System.Net.Security.RemoteCertificateValidationCallback AddressOf _
 ValidateCertificate)
 Dim myUri As New Uri("https://" & Specific.IP_address _ &  "/hp/device/this.LCDispatcher?nav=hp.Config")

 Dim mySP As System.Net.ServicePoint = _

     System.Net.ServicePointManager.FindServicePoint(myUri)
 Stream = wc.OpenRead(myUri)
 Using sr As New System.IO.StreamReader(Stream)
 str = sr.ReadToEnd()
 Stream.Close()
 End Using
 Return CType(CountStr, Integer)
Catch ex As Exception
 Dim errorstring = ex.Message
End Try

вторник, 27 апреля 2010 г.

MVC.Многостраничный просмотр таблицы.

Задача сводится к следующему. При выводе данных в окно браузера ограничиться некоторым количеством записей из таблицы, чтобы помещалось на экране. А тажке соорудить навигацию для доступа к невидимой части.
"MVC PageIndex" - запрос к Google.
Решение очень быстро нашлось. http://en.webdiyer.com/ . Абсолютно бесплатный модуль. Есть очень понятные примеры. http://en.webdiyer.com/MvcPager/Demo/StandardТак как я использую сначала фильтр, а потом уже вывожу данные, то вот мой измененный код:

Function Consumable(ByVal id1 As Integer?) As ActionResult
 Dim Datacontext As New PrintModelDataContext
 Dim ListConsumables As IQueryable(Of ClassConsumable)
 ListConsumables = From c In Datacontext.consumable, p In Datacontext.Printer _
                  Where c.Id_printer = p.Id _
                  Select New ClassConsumable _
                             With {.Id = c.Id, _
                                   .Naim = c.Naim, _
                                   .Part_number = c.Part_number, _
                                   .Revolving = c.Revolving, _
                                   .Count = c.Count, _
                                   .NaimPrinter = p.Naim}
 Return View(ListConsumables.ToPagedList(IIf(id1 Is Nothing, 1, id1), 20))
End Function


Мне пришлось создать новый класс, который является неким объединением двух таблиц Consumable и Printer. Ну а в представлении я абсолютно точно копирую из оригинала. Только перевожу в синтаксис языка  VB

<%=Html.Pager(Of print.ClassConsumable)(Model, New PagerOptions With {.PageIndexParameterName = "id1"})%>

И еще полезно будет в Web.config в каталоге VIEW внести строчку

<namespaces>
<add namespace="Webdiyer.WebControls.Mvc"/>
</namespaces>

Чтоб метод Pager был доступен в каждой странице проекта.

пятница, 19 марта 2010 г.

MVC. Html.DropDownList

Эта тема перекликается с описанной в прошлом посте. Но теперь хочется, чтобы при редактировании и добавлении новой записи, вместо идентификаторов-ссылок на первичные ключи был выбор ввиде выпадающего списка. То есть вместо Html.TextBox используем Html.DropDownList. Вот код в контроллере:

Function CreateSpecific() As ActionResult
Dim Datacontext As New PrintModelDataContext
Dim PrinterList As IList
PrinterList = (From p In Datacontext.Printer Select ID = p.Id, Naim = _ p.Naim).ToList
ViewData("PrinterList") = New SelectList(PrinterList, "ID", "Naim")
Return View()
End Function

А теперь используем список всех принтеров для выбора поля ID_Printer в таблице Specific в представлении:

<%=Html.DropDownList("Id_printer", CType(ViewData("PrinterList"), SelectList)%>

Если у нас есть логическое поле в таблице, то для него тоже можно использовать HTML.DropDownList.
Например в контроллере создаем список:

Dim YesNo As New List(Of SelectListItem)
YesNo.Add(New SelectListItem With {.Value = Boolean.Parse("True"), _
.Text = "ДА",  .Selected = Boolean.Parse("True")})
YesNo.Add(New SelectListItem With {.Value = Boolean.Parse("False"),_
.Text = "НЕТ", .Selected = Boolean.Parse("True")})
ViewData("YesNo") = New SelectList(YesNo, "Value", "Text")

А в представлении код тот же:

<%=Html.DropDownList("Boolean", CType(ViewData("YesNo"), SelectList)) %>
 

MVC. Выводим в представлениях вместо ID - наименования.

Продолжаем работать над MVC приложением. Конечно при отображении значений полей в записи таблицы,  хотелось бы видеть не идентификаторы-ссылки на другую таблицу ,связанную отношениями, а их смысловые значения. Допустим есть  первичная таблица Printer (Это таблица моделей принтеров).  Вот как выглядит контроллер для отображения этой таблицы .

Function Printer() As ActionResult
Dim Datacontext As New PrintModelDataContext
Dim List = From p In Datacontext.Printer Select p
Return View(List.ToList)
End Function

Потом в одноименном представлении (строго-типизированном) мы в цикле выводим колонки записи таблицы.

<%For Each item In Model%>
<%= Html.Encode(item.Naim) %>
<%= Html.Encode(item.Part_number) %>
<%= Html.Encode(item.Manufactory) %>
<%Next%>

А вот выводим дочернюю таблицу Specific:

Function Specific() As ActionResult
  Dim Datacontext As New PrintModelDataContext
  ViewData("Specific") = _
  From s In Datacontext.Specific, _
    p In Datacontext.Printer, _
    f In Datacontext.Filial _
   Where s.Id_Printer = p.Id And s.Id_Filial = f.Id _
   Select s.Id, s.Inv, s.SN, NaimPrinter = p.Naim,_
    NaimFilial = f.Naim
   Return View()
End Function

В представлении мы уж используем Viewdata("Specific") вместо Model.
В этом случае Intellisense уже вам не подскажет.

<%For Each item In ViewData("Specific")%>
<%=Html.Encode(item.NaimPrinter)%>
<%= Html.Encode(item.SN)%>
<%= Html.Encode(item.Inv)%>
<%=Html.Encode(item.NaimFilial)%>
<% Next%>

Вместо поля числового поля ID_printer Выводиться NaimPrinter из таблицы Printer, вместо ID_Filial - NaimFilial

среда, 17 марта 2010 г.

MVC Repository pattern VB

Вот такие ключевые слова мне понадобились для работы над моим первым MVC проектом. Начал я с изучения проекта Nerddinner http://nerddinnerbook.s3.amazonaws.com/Intro.htm Именно там и используется Repository. То есть набор методов над LINQ to SQL для работы с базой данных. Вот пример добавления строки в таблицу dinner:

public void Add(Dinner dinner) {
db.Dinners.InsertOnSubmit(dinner);
}


Вот пример поиска по ID в таблице dinner:

public Dinner GetDinner(int id) {
return db.Dinners.SingleOrDefault(d => d.DinnerID == id);
}


Так как в проекте Nerddinner используется только одна таблица, то это разработчиков устраивает. Но в моей базе данных 7 таблиц, и видимо есть способ не писать один и тот же код для всех таблиц. И вот в инете нахожу ссылку на универсальный Repository.
http://mikehadlow.blogspot.com/2008/03/using-irepository-pattern-with-linq-to.html
Только мне нужен на VB.
И вот предлагаю небольшую адаптацию написанную на VB.
Добавление записи в таблицу:

Public Sub Add(Of T)(ByRef Tab As T)
dc.GetTable(GetType(T)).InsertOnSubmit(Tab)
End Sub

Action метод для создания записи в таблице Printer будет такой:

Function CreatePrinter(ByVal Row As Printer) As ActionResult
Try
Datawork.Add(Of Printer)(Row)
Datawork.Save()
Return RedirectToAction("Printer")
Catch
Return View()
End Try
End Function


Удаление делается аналогично:

Public Sub Delete(Of T)(ByRef Tab As T)
dc.GetTable(GetType(T)).DeleteOnSubmit(Tab)
End Sub

А вот универсальный поиск по ID оказался для меня сложнее.

Public Function GetbyID(Of T)(ByVal ID As Int32) As T
Dim NameOfTable As ParameterExpression = Expression.Parameter(GetType(T), "x")
Dim lambda1 As Expression(Of Func(Of T, Boolean)) = _
Expression.Lambda(Of Func(Of T, Boolean))( _
Expression.Equal(Expression.Property(NameOfTable, "ID"), Expression.Constant(ID, GetType(Integer))), _
New ParameterExpression() {NameOfTable})
Return CType(dc.GetTable(GetType(T)), IQueryable(Of T)).SingleOrDefault(lambda1)
End Function

Для понимания Lambda Expression рекомендую ссылку http://chakkaradeep.wordpress.com/2008/04/14/c-30-language-enhancements-for-linq-part-3-expression-trees/ . Мне она очень помогла.

пятница, 5 марта 2010 г.

QNAP TS-219P не подсоединяется к домену Windows 2003

Вот уж где не ожидал наткнуться на проблему. Казалось бы ничего сложного нет, просто нужно ввести в окно настроек параметры подключения к домену:
имя сервера контроллера домена, имя домена, имя администратора и пароль. И в итоге получаю ошибку "Microsoft network settings failed " и трачу несколько часов на ее решение.

Вот, наконец-то, в инете нашел ответ.
http://forum.qnap.com/viewtopic.php?f=20&t=12033&start=20
Оказывается нужно было догадаться, что параметр WORKGROUP  устанавливается в короткое имя домена.
Настройка подключения выглядит следующим образом:



Обратите внимание на WORKGROUP . Нет ничего похожего в справке об этой проблеме.

среда, 17 февраля 2010 г.

Проблема с Microsoft Office 2003 (Не запускается,не удаляется,не устанавливается)

Проблема указана в заголовке. Выглядит это вот так:

 
Началось с того, что я удалил Офис, потом его установил. А затем сделал восстановление системы на контрольную точку, где офис уже стоял. После этого случается такая засада. Ни запустить, ни удалить, ни переустановить не могу - вылетает ошибка. Ищу в инете решение. "Office install problem" - вот строка поиска. И одна найденная страничка  отправила меня вот сюда : kb290301 . Windows Installer CleanUp - средство для решения таких проблем.

понедельник, 25 января 2010 г.

Новый принтер HP P4515x выдает ошибку 49.4С27

Пришли два новых принтера HP P4515x. Один пришел в ноябре, другой - в декабре. Абсолютно одинаковые принтера, а работают по разному. Так вот, первый принтер выдает постоянно ошибку 49.4С27, независимо от интерфейса подключения. Оказывается куплены принтера с разницой в месяц,а  firmware у них разный. Тут и гадать не пришлось в чем дело. Иду на сайт HP http://h20000.www2.hp.com/bizsupport/TechSupport/SoftwareDescription.jsp?lang=en&cc=us&prodTypeId=18972&prodSeriesId=3558888&prodNameId=3558895&swEnvOID=54&swLang=33&mode=2&taskId=135&swItem=hv-61299-5 и качаю прошивку ) 04.049.3. Старая прошивка была 04.48.4. Вот так покупаешь новый принтер и уже голову ломаешь над ошибками.
Несколько замечаний по эксплуатации HP P4515.
Термоузел на одном принтере заменил на 400000 пробеге, на другом 225000. Второй принтер выдал ошибку 50.4 и отказался дальше  печатать пока не заменил термоузел (CB389-67901 Ремкомплект LJ P4014/4015/P4515 CB389A).
Так как  замечено, картриджи для HP P4515 выдают меньше копий, чем картриджи для HP 4350, попробывал в драйверах выставить Econome mode. Качество копий в таком режиме меня устраивает. Экономию нужно еще посчитать.
Добавляю вдогонку. В Econom mode существенно экономит тонер. С 15000 страниц до 20000. Советую пользоваться. Качество документов - приемлимое.

среда, 20 января 2010 г.

Удаление стандартных игр WIndows XP

Много есть вариантов в инете. Но я реализовал вот этот, вот по этой ссылке:
http://www.tek-tips.com/viewthread.cfm?qid=1070019&page=14.
Итак, идея проста,  для удаления воспользоваться утилиткой sysocmgr.

Dim Fso : Set Fso = CreateObject("Scripting.FileSystemObject")
Set WshShell = WScript.CreateObject("WScript.Shell")
sPrograms = WshShell.SpecialFolders("AllUsersPrograms")
If (Fso.FolderExists(sPrograms & "\Игры")) Then ' Create file for uninstalling games
Set f = Fso.CreateTextFile("c:\windows\inf\wmdtocm.txt", True)
f.WriteLine("[Components]")
f.WriteLine("freecell=off")
f.WriteLine("hearts=off")
f.WriteLine("minesweeper=off")
f.WriteLine("msnexplr=off")
f.WriteLine("pinball=off")
f.WriteLine("solitaire=off")
f.WriteLine("spider=off")
f.WriteLine("zonegames=off")
f.Close
WshShell.Run "sysocmgr.exe /i:c:\windows\inf\sysoc.inf /u:""c:\windows\inf\wmdtocm.txt"" /q", 1, True
Fso.DeleteFolder(sPrograms & "\Игры"), True
End If


Код практически такой же, как в оригинале, только изменена папка, где хранятся игры. В русской версии WindowsXP - это "\Игры".
Этот код сохраните в файл с расширением ".vbs". Допустим remove_games.vbs
Для того чтобы удалить игры со всех компьютеров домена, можно использовать групповую политику. Я включил этот скрипт в автозагрузку.
"Конфигурация компьютера->Конфигурация Windows->Сценарии (запуск завершение)->Автозагрузка." Это работает и можно использовать

среда, 13 января 2010 г.

WinToDos. Как сохранить данные в DOS кодировке.

Думаете задача неактуальная. Ошибаетесь. Вы знаете, что Сбербанк принимает файлы на зачисление на пластиковые карты в DOS формате. Информация на зачисление выгружается из "1С Кадры и Зарплата" в формате XML, после этого нужно получить DOS-файл со списком на зачисление.
Сейчас это делается на VBA в EXCEL. Я решил переписать на VB2008. Вот как функция перекодировки  выглядит на VBA (Авторство не моё):

W = "": D = ""
For I = 192 To 255: W = W & Chr$(I): Next
For I = 128 To 175: D = D & Chr$(I): Next
For I = 224 To 236: D = D & Chr$(I): Next

Public Function WinToDos(ByVal S As String, ByVal W As String, ByVal D As String) As String
Dim R As String
Sym = S: Ltext = Len(S)
If Ltext > 0 Then
For I = 1 To Ltext
k = InStr(W, Mid(S, I, 1))
If k > 0 Then
Mid(Sym, I, 1) = Mid(D, k, 1)
End If
Next I
End If
WinToDos = Sym
End Function

То есть понятно. Создается две строки. Одна содержит символы в Windows кодировке, другая в DOS. Первый параметр - строка,которую нужно перекодировать.Затем в цикле меняем один символ на другой.
Можно было использовать и этот код. Ну уж больно хотелось использовать возможности .NET.
И вот что получилось. Вот пример программы создающий файл с данными в DOS кодировке.

Imports System
Imports System.IO
Imports System.Text

Module Module1
Sub Main()
Dim Sym As String = "Привет от старых штиблет"
Dim encoding1 As Encoding = Encoding.GetEncoding(866)
Dim ioFile As New _
StreamWriter("c:\proba.txt", Boolean.Parse("False"), encoding1)
ioFile.WriteLine(Sym)
ioFile.Close()
End Sub
End Module

В файле proba.txt в DOS кодировке будет строчка "Привет от старых штиблет"

Gmer.exe снова помог

При включении сервер не появился в сети. Итак, приступаем к расследованию причин.  Оказалось, в устройствах компьютера в разделе "сетевые платы" плата Intel 82566DM помечена восклицательным знаком на фоне желтого круга. Устройство работает неверно. Пытаюсь установить драйвер снова. Не устанавливается. Удаляю плату . Удаляю драйвера. Все устанавливаю заново . Результат тот же. Итак я шаманил с часок, пока до меня не дошло, что возможно это вирус. Запускаю Gmer.exe. Сразу же бросается в глаза красным цветом выделенный процесс Net.exe.  Ну а дальше гашу этот процесс и удаляю файл, который его запускает. После этого все встаёт на свои места. В последнее время все чаще причиной разных проблем становяться вирусы. Поэтому, к самому распространенному совету по решению проблем "Перегрузись", я думаю, нужно еще добавить "Проверь на вирусы".