WSS: Hromadné odstranění záznamů v listu

Pokud jste někdy potřebovali kompletně vyprázdnit list/knihovnu dokumentů, určitě jste rychle narazili, stejně jako já, na neexistenci takové funkce. Samozřejmě je možné mazat jednotlivé záznamy v iteraci, to je ale velice časově nákladná operace, kterou nejde použít ani na desítkách záznamů 🙁 Smazání jednoho záznamu trvá klidně i 500ms, 1000 záznamů by se tedy mazalo 5-10 minut.

Nakonec jsem našel trošku krkolomné řešení, které je však řádově rychlejší než mazání v iteraci. Základem celé akce je složení velkého XML balíku hromadného příkazu pro smazání jednotlivých záznamů v jednom volání. Vtip je v tom, že i když toto řešení také iteruje celým seznamem v listu, property ID je u SPListItem už přednačtena v cache Sharepointu, ten tedy nemusí pro každou iteraci sahat do DB, složení tak může proběhnout rychle. Výsledný balík se už jen předhodí enginu WSS, který jej interně zpracuje. Po ukončení ještě v mém případě volám vyprázdnění koše aktuálně přihlášeného uživatele, to samozřejmě není nutné a může být v některých případech i kontraproduktivní při volání pod „real-life“ uživatelem.

Pokud existuje lepší cesta, určitě bych se nechal rád inspirovat 🙂

private static void BatchListItemsDelete(SPList spList)
{
    StringBuilder sbDelete = new StringBuilder();
    sbDelete.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Batch>");
    string command = "<Method><SetList Scope=\"Request\">" + spList.ID +
        "</SetList><SetVar Name=\"ID\">{0}</SetVar><SetVar Name=\"Cmd\">Delete</SetVar></Method>";

    foreach (SPListItem item in spList.Items)
        sbDelete.Append(string.Format(command, item.ID.ToString()));

    sbDelete.Append("</Batch>");

    spList.ParentWeb.ProcessBatchData(sbDelete.ToString());
    spList.ParentWeb.RecycleBin.DeleteAll(); 
}

Kniha zdarma: Virtualizační řešení (MS Press)

„V jednotlivých kapitolách se dočtete o typech virtualizace a pak samozřejmě o každé z nich zvlášť. Těšit se můžete na informace o Hyper-V, SC Virtual Machine Manageru, aplikační virtualizaci APP-V, prezentační virtualizaci za pomoci Terminal Services, desktopové virtualizaci MED-V a VDI, plus samozřejmě spoustu tipů a rad na stavbu virtualizačních řešení přesně pro vaše potřeby!“

http://csna01.libredigital.com/?urmvs17u33

http://blogs.technet.com/technetczsk/archive/2009/02/04/ms-press-zdarma-kniha-virtualizacni-reseni.aspx

Modifikace zamrzávající IP kamery Edimax IC-1500

Pokud uvažujete o koupi IP kamery a ještě jste se nerozhodli, určitě se vyhněte kameře Edimax IC1500. Tato kamera obsahuje nespočet chyb a vad, třeba:

  • přehřívá se = po nějaké hodině se zasekne, funguje ping, nefunguje však webserver, takže je nutné kameru ručně odpojit od sítě a znovu zapojit 🙁 Opravdu velice praktické
  • dodávána s velice špatným SW, se kterým je problém už jen nakonfigurovat wifi
  • při upgradu firmwaru je opět v továrním nastavení, musíte jí tedy komplet znovu konfigurovat po LAN, tedy všechny kamery obejít a zdlouhavě nastavovat
  • s novým firmwarem je omezen framerate na 5 FPS = čínská oprava přehřívání
  • resetování je stejně komplikované jako nastavení:
    • Unplug power
    • Hold in rest button with small screwdriver
    • Power back on but continue to hold reset for almost 30 seconds.
    • Release reset once you see the two status lights on the lens flash twice.
    • Power off the unit
    • Power back on
    • Configure from the windows admin utility – it should find it with the „search“ button.
    • Power cycle once more and confirm settings are intact
  • zobrazit kameru je možné pouze v IE (díky ActiveX)
  • nefungují automatické korekce obrazu, ta funkce tam je, obraz je ale příšerný

To je jen krátky seznam na který jsem si dokázal rychle vzpomenout.

Kamera má však i jednu výhodu, opravdu ale jen jednu, firmware je kompletně open source, takže si ho kdokoliv může upravit k obrazu svému. 

Pokusil jsem se odstranit přehřívání HW modifikací casu kamery, po rozebrání jsem na všechny horké součástky připevnil hliníkové chladiče, ze zadní části jsem odstranil plechový kryt a do spodní části jsem vyříznul otvor pro nově přidaný ventilátor.

Výsledek je zde:

A jak to dopadlo se zasekáváním? Trošku jsem si pomohl, kamera se už nezasekává po hodině provozu, ale cca po několika dnech ;-(

Naštěstí se mi již podařilo přijít i na způsob, jak toto zasekávání odstranit úplně, dnes už ale nemám sílu to popisovat.

Zobrazení aktuálních aktivit Microsoft CRM 4 v Sharepointu + zdrojové kódy

Na tomto příspěvku jsem chtěl demonstrovat jednoduchost a vůbec možnost provázání různých aplikací s Sharepointem. Rozhodl jsem se pro vytvoření webparty, zobrazující aktuálně přiřazené a nesplněné aktivity v Microsoft CRM 4, protože to bude určitě užitečná featura pro spoustu lidí využívajících firemní intranet.

Takto vypadá výsledný webpart (po kliknutí na daný předmět aktivity se otevře přímo v editačním okně CRM):

 

Takto jsou zobrazeny aktivity v CRM:

Zdrojové kódy i WSP balíček je přiložen na konci tohoto postu.

Načítání aktivit z CRM serveru probíhá přes webservice, url adresa webové služby je vždy ve formátu:

http://server:port/MSCRMServices/2007/CrmService.asmx

Pokud používáte Visual Studio 2008, je potřeba vygenerovat klientský wrapper až v „Advance“ dialogu jako na následujícím screenshotu:

 

Aby bylo možné rozlišit aktuálně používanou organizaci zavedenou v CRM, je potřeba ještě provést nastavení objektu CrmAuthenticationToken jako na následujícím příkladu:

public static CrmService GetCrmService(string crmServerUrl, string organizationName)
        {
            if (string.IsNullOrEmpty(crmServerUrl)) throw new ArgumentNullException("crmServerUrl");
            if (string.IsNullOrEmpty(organizationName)) throw new ArgumentNullException("organizationName");

            CrmSdk.CrmAuthenticationToken token = new CrmSdk.CrmAuthenticationToken();
            token.OrganizationName = organizationName;

            CrmService service = new CrmService();
            UriBuilder builder = new UriBuilder(crmServerUrl);
            builder.Path = "//MSCRMServices//2007//CrmService.asmx";
            service.Url = builder.Uri.ToString();
            
            service.Credentials = System.Net.CredentialCache.DefaultCredentials;
            service.CrmAuthenticationTokenValue = token;

            return service;
        }

 

Aby jsme mohli vyhledat svoje aktivity, je nejprve nutné zjistit identifikátor přihlášeného uživatele:

WhoAmIRequest request = new WhoAmIRequest();
WhoAmIResponse response = (WhoAmIResponse)service.Execute(request);
Guid userId = response.UserId;

Pak už jen stačí vyhledat aktivity s přiřazeným vlastníkem na sebe sama a nastaveným status kódem – open nebo scheduled.

private static BusinessEntityCollection GetAssignedActivities(CrmService crmService, Guid userId)
        {
            // budeme nacitat aktivity prirazene prihlasenemu uzivateli
            ConditionExpression condition = new ConditionExpression();
            condition.AttributeName = "ownerid";
            condition.Operator = ConditionOperator.Equal;
            condition.Values = new object[] { userId };

            // potrebujeme pouze otevrene aktivity
            ConditionExpression condition2 = new ConditionExpression();
            condition2.AttributeName = "statecode";
            condition2.Operator = ConditionOperator.Equal;
            condition2.Values = new object[] { (int)ActivityPointerState.Open };
            ConditionExpression condition3 = new ConditionExpression();
            condition3.AttributeName = "statecode";
            condition3.Operator = ConditionOperator.Equal;
            condition3.Values = new object[] { (int)ActivityPointerState.Scheduled };

            FilterExpression filterState = new FilterExpression();
            filterState.FilterOperator = LogicalOperator.Or;
            filterState.Conditions = new ConditionExpression[] { condition2, condition3 };

            FilterExpression filterRequired = new FilterExpression();
            filterRequired.FilterOperator = LogicalOperator.And;
            filterRequired.Conditions = new ConditionExpression[] { condition };

            FilterExpression filter = new FilterExpression();
            filter.FilterOperator = LogicalOperator.And;
            filter.Filters = new FilterExpression[] { filterRequired, filterState };

            // seradime podle konce aktivity
            OrderExpression order = new OrderExpression();
            order.AttributeName = "scheduledstart";
            order.OrderType = OrderType.Ascending;
            
            // vytvoreni vyhledavaciho dotazu - potrebujeme vsechny aktivity
            QueryExpression query = new QueryExpression();
            query.EntityName = EntityName.activitypointer.ToString();
            query.ColumnSet = new AllColumns();
            query.Criteria = filter;
            query.Orders = new OrderExpression[] { order };

            // vykonani samotneho dotazu
            return crmService.RetrieveMultiple(query);
        }

 

 Následně již stačí vyrenderovat všechny položky do HTML. Prosté, ale dobré 🙂

Instalace feature:

cd C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\BIN

stsadm -o addsolution -filename crm4connector.wsp

stsadm -o deploysolution -name crm4connector.wsp -immediate -allcontenturls -allowGacDeployment -allowCasPolicies

následně aktivujte feature ve správě webu:

 

Přidejte feature „Activities in CRM“ na libovolnou stránku:

 

V nastavení feature je nutné ještě nastavit url adresu serveru s Microsoft CRM 4 a název organizační jednotky: 

(níže je také možné upravit obecné texty podle potřeby – podle aktuálně používaném jazyku)

 

Hotovo, po potvrzení by se měl zobrazit seznam aktivit aktuálně přihlášeného uživatele. Pokud je něco špatně, budete upozorněni:

Ke stažení:

sources.zip (272,14 kb)

bin.zip (244,01 kb)

Hyper-V™ Server 2008 R2 Beta

Byla uvolněna beta verze Hyper-V Serveru 2008 R2, několik připravovaných novinek:

– live migrace VPC za jeho provozu, bude tedy možné vytvořit virtualizované PC s vysokou dostupností a kdykoliv ho přesunout na jiný node bez zastavení
– za provozu bude také možné připojit/odpojit pevné disky
– bude se jednat o "zelený" stroj, Hyper-V bude automaticky vypínat/zapínat jednotlivá jádra CPU podle zatížení

Stahujte zde:
http://www.microsoft.com/downloads/details.aspx?FamilyID=e464e255-cdd5-44b2-84e6-3233eae3f356&displaylang=en

 

Microsoft Tag

Microsoft na CES09 uvedl obdobu QR tagu, který je patentovaný firmou Denso Wave.

Hned na první pohled je vidět rozdíl a podle mě i vážný nedostatek Microsoft Tagu, ten totiž používá pro zakódování informací CMYK barvy, QR tag je pouze černobílý. Plyne z toho hned několik omezení: s čenobílou laserovou tiskárnou máte smůlu, potřebujete relativně kvalitní optiku snímajícího zařízení a dobré osvětlení, jinak se nepodaří kód přečíst. QR má v tomto jistě velikou výhodu, protože ho můžete poslat faxem, najít v černobílém tisku, scanovat i v poměrně velice tmavém prostředí.

Tagy mají i kapacitní rozdíl, na QR tag je možné uložit až 4296 alfanumerických znaků, na Microsoft Tag je možné uložit pouze unikátní identifikátor, všechny související data si klient musí načíst ze serveru. Každý způsob má nějaké plus a nějaké mínus, u QR tagu si však logicky můžete také uložit pouze identifikátor.

 

Microsoft Tag:

 

QR Code: 

 

Microsoft Tag: http://tag.microsoft.com/SignIn.aspx

Video tutorial instalace a konfigurace Search Serveru 2007 Express

Narazil jsem při brouzdání na MSDN na odkaz o který se rád podělím, jedná se o video tutorial instalace a konfigurace Search Serveru 2007 Express

http://www.microsoft.com/winme/0711/31250/Installation_and_Config/Default.html

EDIT:

našel jsem ještě pokračování:

http://www.microsoft.com/winme/0711/31250/End_User_Experience/Default.html

http://www.microsoft.com/winme/0711/31250/Federation/Default.html

Nastavení XML-RPC.NET programově bez nutnosti existence konfiguračního souboru

Jelikož se mi v aktuálním projektu nehodila existence konfiguračního souboru aplikace (app.config) pro zajištění konfigurace XML RPC serveru ve vlastní assembly, potřeboval jsem stejné parametry nastavit programově.

Nakonec jsem narazil na odpověď:

ListDictionary prop = new ListDictionary();

prop.Add("port", 1971);

HttpChannel channel = new HttpChannel( prop, null, new XmlRpcServerFormatterSinkProvider(null, null));

ChannelServices.RegisterChannel(channel);

RemotingConfiguration.RegisterWellKnownServiceType( typeof(Server), "myApp/anURI", WellKnownObjectMode.Singleton);