Publikování SCSF/CAB aplikace pomocí ClickOnce
03 února 09 04:45 odp.

Abych se nechlubil cizím peřím, musím přiznat, že tento návod je více méně překladem z Raj's .NET Blog. Jenom si to chci ověřit na vlastní kůži, někde zestručnit, někde se víc rozepsat a vše uchovat pro pozdější použití :-). Nebudu se zabývat vytvořením SCSF aplikace ( na zmíněném blogu je velmi vhodný příklad - tento návod se ho více méně drží ), ale čistě jenom otázkou publikování. Tento návod je napsán stylem "pro blbce" ( tj. hlavně pro mě :-) ) a proto prosím zkušené vývojáře, aby dál nečetli a případně mě za to komentářích nefackovali.

I. Nastavení Shell projektu

Zatím postupujeme tak, jak jsme zvyklí. V Shell projektu zvolime "Properties" a zvolíme záložku "Publish". Jako adresář pro publikování můžeme nastavit najaký adresář na lokálním ( případně síťovém ) disku, kde máme možnost zápisu. Nejlépe ale někde v IIS našeho počítače. Predpokladem je v takovém případě správně nainstalová a funkční IIS.

Takže cesta k adresáři pro publikování může vypadat třeba následovně:

C:\Inetpub\wwwroot\TEST\SCSF_TestApp

URL pro instalaci pak zřejmě bude:

http://adresa_meho_pc/TEST/SCSF_TestApp/

Ponecháme nastavení, že aplikaci je možné používat i v offline režimu a automatické navyšování čísla revize.

Zvolíme "Publish Now", případně "Publish Wizard...", pokud si chceme nastavení ještě jenou prohlédnout.

Pokud vše proběhlo v pořádku, otevře se nám v internetovém prohlížeči stránka "publish.htm"  s nejakými informacemi o aplikaci a tlačítkem "Install". Vyzkoušejme si tedy stáhnout "Setup.exe" a nainstalovat aplikaci. Po nainstalování a spuštění zjistíme, proč se musí změnít přístup při publikování SCSF aplikací oproti ostatním - aplikace se chová, jaky by neměla u sebe žádný modul ( i když při debugu z VS se všechny moduly spouští správně ).

Osobně jsem se setkal s problémem, že pokud byl jako adresář pro publikování nastaven NE-webový adresář sdílený v lokální síti ( např. C:\TEST\SCSF_TestApp ) a jako instalační URL pro publikovanou aplikaci bylo tím pádem \\muj-pocitac\TEST\SCSF_TestApp, aplikace se sice zacala instalovat, nicméně instalace záhy skončila chybou "Aplikace nejde stáhnout", jelikož nelze nalézt soubor "<moje_uplne_puvodni_cesta_k_umistneni_projektu>.SCSF_TestApp.application". I kdyz soubor SCSF_TestApp.application byl v adresáři pro export, hledal se uplne nekde jinde ( tj. v adresáři původního projektu ). Pokud někdo ví, kde jsem udělal chybu, nechť mě prosím upozorní v diskuzi.

II. Vytvoření kopie publikovaného shell projektu

Pro přilepení chybejících modulů bude třeba vytvořit nový aplikace manifest soubor a publikační manifest soubor. Přejděme do adresáře, kde je publikována naše aplikace - v tomto případě C:\Inetpub\wwwroot\TEST\SCSF_TestApp\Application Files a vytvoříme novou revizi tak, že zkopírujeme obsah adresáře Shell_1_0_0_0  do nově vytvořeného adresáře Shell_1_0_0_1.

Nyní do nově vytvořeného adresáře zkopírujeme soubory ( knihovny ), které nám oproti <adresar_s_projektem>\bin\Release chybí. Bude se zřejmě jednat o Infrastrusture.Layout.dll, Infrastrusture.Module.dll a knihovny s námi vytvořených komponentami ( např. buttonModule.dll, buttonModule.Interface.dll, atd... ).

III. Úprava manifestů

Na upravu manifestu použijeme nástroj MageUI.exe. Spustit se ho můžeme pokusit z příkazové řádky Visual Studia ( View -> Other Windows -> Command Window Ctrl+Alt+A ), pokud se to nepodaří, je jeho obvyklé umístnění v adresáři C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin. V programu Mage otevřeme manifest soubor Shell.exe.manifest z nově vytvořeného adresáře Shell_1_0_0_1. Změníme verzi tak, aby odpovídala vytvořenému adresáři ( tj. 1.0.0.1 ). Dále vybereme ze seznamu na levé straně položku "Files" a následuje kliknutí na "Populate".

V Solution Exploreru ve Visual Studiu zjistíme, kde je uložený soubor náš vygenerovaný klíč pro podepsání manifestu ( pokud používáme generovaný pro podepsání ClickOnce manifestu ). Většinou bude cesta k němu vypadat takto:  Source\Infrastructure\Shell\Shell_TemporaryKey.pfx. Tento klíč zkopírujeme do adresáře, kde jsme publikovali naši aplikaci ( tj. C:\Inetpub\wwwroot\TEST\SCSF_TestApp ). Nyní dáme uložit náš upravený manifest ( možná na nás vyletí nejaká chybka o validaci ) a následně dialogové okno pro podepsání manifestu. Zvolíme možnost "Sign with certificate", vybereme nedávno zkopírovaný klíč z adresáře pro publikování a klikneme na OK. Nyní máme vytvořený aplikační manifest.

Pustíme se do úpravy deploy manifestu, který se nachází v adresáři pro publikování ( NE ve verzových adresářích, kde se nachází aplikační manifest ). Otevřeme soubor Shell.application a znovu opravíme verzi na naši vytvářenou ( tj. 1.0.0.1 ). V levém seznamu vybereme položku "Application Reference", pak klikneme na "Select Manifest..." a v dialogovém okně vybereme náš před chvílkou upravený manifest. Dáme uložit a podepíšeme našim klíčem stejně jako v předchozím případě.

Nyní máme vytvořenou verzi 1.0.0.1 a můžeme si ji spuštěním setup.exe souboru ( nebo spuštěním předchozí nainstalované verze ) nainstalovat. Pokud naše nová verze při spuštění spadne, je pravděpodobné, že se na některou z knihoven zapomělo při kopírování do adresáře verze. Jejich dodatečná instalace je trochu otrava, protože musíme najít nechutně nazvaný adresář s instalací někde v Local Settings daného uživatele a tam chybějící knihovny donahrávat.

IV. Vytvaření dalších verzí

Vytvoříme kopii poslední verze ( v našem příkladu Shell_1_0_0_1 ) do nového adresáře s inkrementovanou verzí ( tj. Shell_1_0_0_2 ).

Novou verzi knihovny se změnou ( např. buttonModule.dll ) zkopírujeme do tohoto adresáře. Následně stejně jako dříve upravíme oba manifesty ( nezapomenou na Populate ) a nová verze je na světě.

Jiná možnost

Existuje ale i možnost ( možná lepší ), jak celý postup zjednodušit a zpohodlnit.

1) Přidáme do Shell projektu reference na projekty, u kterých jsme museli DLL kopírovat růčo: Infrastrusture.Layout, Infrastrusture.Module, Infrastructure.Interface a projekty s námi vytvořenými komponentami ( např. buttonModule.dll, buttonModule.Interface.dll, atd... ).

2) V Shell projektu zaškrtneme Project Dependecies na projekty, které jsme přidali do references. Pokud tento krok neuděláme, nesmíme zapomenout vždy před publikováná zkompilovat změněný projekt a jeho DLL nahrát do Release adresáře Shell projektu.

3) Ve vlastnostech souboru ProfileCatalog.xml nastavíme ( pokud není ) "Build Action" na "Content a Copy to output" directory na "Copy always"

4) Shell projekt -> Properties -> Publish -> Application Files ... -> Nastavit ProfileCatalog.xml na Include.

Postedby tomino | 35 Comments    
Vedeno pod: , , ,
BulkLoad - Chyba invalid connection string
15 srpna 08 11:19 dop.

Po delší době jsem byl nucen využít kdysi napsaný program pro kopírování dat z XML do DB.

Upravil jsem ConnectionString tak, jak jsem potřeboval a dostal jsem chybu "Invalid connection string". Je to zvlaštní, když connection string je napsaný určitě dobře... Hledám chvíli na netu a nic rozumného nenacházím.

Po chvíli porovnávání s předchozí funkční verzí v SVN jsem zjistil, že přece jenom drobný, ale zato podstatný rozdíl v ConnectionStringu tu je.

BulkLoad totiž vyžaduje jiného providera. Proto je nutné mít před ConnectionStringem položku Provider=sqloledb;

ConnectionString by měl vypadat asi takto:

Provider=sqloledb; Data Source=MyDataSourceServer;Initial Catalog=MyDB;Persist Security Info=True;User ID=admin;Password=securePassword

Postedby tomino | 3 Comments    
Vedeno pod: , ,
Chyba při pokusu o připojení do PostgreSQL přes OPENROWSET
20 prosince 07 11:21 dop.
Tento příspěvek je spíš pro mou vlastní paměť, než aby popisoval něco užitečného, ale možna někomu usnadní par desítek minut nadávání u PC a googlování.

Databáze pro MS SQL Server se přesunula na jiný stroj. Spouštěl se nad ní skript, který chodil pro data do DB v PostgreSQL.
Objevila se chyba o špatné autentizaci, což je divné, protože login a heslo jsou shodné a neměnily se.

Chyba:
Msg 7399, Level 16, State 1, Line 1
The OLE DB provider "MSDASQL" for linked server "(null)" reported an error. Authentication failed.
Msg 7303, Level 16, State 1, Line 1
Cannot initialize the data source object of OLE DB provider "MSDASQL" for linked server "(null)".

Po delším bádání ( a při pokusu o vytvoření uživatelského DSN z onoho nového serveru za pomocí nových driverů ) se konečně zjistilo, kde se stala chyba, protože už to vyhodilo smysluplnou chybovou hlášku.

Nesmí se zapomenout upravit v PostgreSQL soubor pg_hba.conf a přidat tam IP nového serveru ( nebo PC ), které k DB přistupuje. Prostě se zapomělo na to, co se dělalo cca před půl rokem :-)


Postedby tomino | 1 Comments    
Vedeno pod: ,
ListView + DataPager a problém s přepínáním
10 prosince 07 01:18 odp.
Narazil jsem na problém, kdy při použití DataPager spolu s ListView nefungovalo přepínání stránek správně. Vypadalo to třeba tak, že reakce na kliknuti např. na čislo stránky DataPageru se spozdila o jeden klik:

Projevovalo se to asi nasledovně:
1. klik na stránku č. 2 -> k přepnutí nedošlo
2. klik na stránku č. 4 -> došlo k přepnutí na stránku č. 2
3. klik na "Zpět" -> Došlo k přepnutí na stránku č. 4
.... atd...

nebo u jednoho ListView se mi dokonce stalo, že se na kliknutí vůbec nereagovalo ( PostBack se provedl, ale stránka v ListView se nezměnila nikdy ).

Řešením bylo zavolat DataBind() v PreRender prvku ListView... pokud z toho není zřejmé, jak to bylo myšleno, tak asi takto:

V souboru neco.aspx/ascx:
<asp:ListView EnableViewState="true" runat="server" OnPreRender="PreRender_lvMujSeznam" ID="lvMujSeznam"  ..... 

V souboru neco.aspx.cs/neco.ascx.cs:
protected void PreRender_lvMujSeznam( object sender, EventArgs e )
{
  lvMujSeznam.DataBind();
}

Bylo by asi dobré podotknout, že metoda DataBind() našeho ListView by se měla volat jenom jednou - tj. smáznout z PageLoad(), pokud tam je...

   
Postedby tomino | 11 Comments    
OPENROWSET - Jednoduhý způsob, jak se rychle připojit k DB na vzdáleném serveru
27 listopadu 07 12:33 odp.
Někdy se může hodit, že např. při nějakém importu do MS SQL 2005 potřebujeme rychle sáhnout pro nějaká data do DB na vzdáleném serveru. 

Jednoduše to můžeme udělat pomocí OPENROWSET a to následujícím způsobem:

SELECT *
FROM OPENROWSET
('SQLNCLI','server=NejakyServer;Database=NejakaDB;Trusted_Connection=yes','select * from NejakaTabulka')


Pokud potřebujeme sáhnout do PostgreSQL DB, lze to následujícím způsobem:
SELECT *
FROM OPENROWSET('MSDASQL',
'DRIVER={PostgreSQL};server=jmenoServeru;UID=mujLogin;Database=JmenoDB;password=mojeHeslo;timeout=1000',
'SELECT * FROM NejakaTabulka') t1

   
Postedby tomino | 0 Comments    
Vedeno pod: , ,
Poznání prvních rozdílů mezi VS 2008beta2 a VS 2008 RTM (a v nové verzi .NET FW)
23 listopadu 07 09:05 dop.

Následující poznatky jsou platné pouze pro můj projekt ve VS, v jiných projektech tomu může být jinak, tak mě prosím nekamenujte, pokud nepopisuje zrovna Vaši situaci :-).

  • První, čeho jsem si všimnul bylo, že se změnily některé verze assembly a bylo tedy potřebné je vyhodit z web.configu, pokud tam byly natvrdo přidány a přidat do referencí novou verzi. V mém případě jsem tak musel udělat pro System.Data.DataSetExtensions (původní verze byla 2.0.0.0, nová je 3.5.0.0).
  • Pokud máme DBML uloženy jako UTF-8 (coz bohuže VS Beta2 s radostí dělalo i přes to, že v XML hlavičče bylo jasně uvedeno, že se jedna o dokument v UTF-16), je potřeba je uložit v UTF-16. Nejjednodušší je otevřít ve VS jako XML a dát uložit.
  • Ve všech ListView je potřeba přejmenovat propery
    GroupContainerID -> GroupPlaceholderID
    a
    ItemContainerID -> ItemPlaceholderID
  • A asi nejpitomější věcí, jakou mohli udělat je, že prvek, který sloužil dříve jako ItemContainer (nyní je jako tzv. ItemPlaceholder) se nerenderuje do vystupu. Přidává to jenom kód navíc. Všechny ItemContainery je potřeba přepsat např. následujícím způsobem (platí i pro Repeater, což je celkem pozdní novinka):
    <UL> id="itmCont" runat="server"></UL> na <UL><asp:PlaceHolder runat="server" ID="ItmCont"></asp:PlaceHolder</UL>. Ale místo PlaceHolderu by mohlo být obecně cokoliv, stejně se to nerenderuje na výstup.

Určitě je toho mnohem víc. Pokud si najdu chvilku, tak dopíšu. Případně uvítám Vaše poznatky v diskuzi.

   
Postedby tomino | 9 Comments    
Default button v ASP.NET 2.0
06 listopadu 07 10:49 dop.
Na tohle téma bylo napsáno mnoho přispěvků do blogů. Pokud se ale chceme vyhnout JavaScriptu v kódu a jiným "ošklivým" řešením a zároveň mít zaručenou funkčnost ve všech možných i nemožných prohlížečích, není to zase tak úplně jednoduché. Je potřeba si uvědomit, že pokud používáme MasterPages a v nich do Form nastavíme atribut DefautButton, dostaneme chybu:
The DefaultButton of 'main_master' must be the ID of a control of type IButtonControl,
protože MasterPage asi nic netuší o nějakém buttonu někde v UserControlu.

Postup, který mě zaujal (a funguje i pod Operou Big Smile ) jsem našel zde: http://weblogs.asp.net/scottgu/archive/2005/08/04/421647.aspx

Prostě se část stránky (uvnitř UserControlu), která má reagovat na "Enter", umístní do <asp:Panel> ... pokud bude focus stránky jinde než na daném panelu, 
nebude se na enter reagovat (a to může být velmi často taky užitečné). Tento panel se už může nacházet v libovolném UserControlu.

<asp:Panel DefaultButton="btn_hledani" ID="panHlMenu" runat="server">
....
<asp:LinkButton SkinID="menu_skin" ID="btn_hledani" runat="server" Text="Hledej" onclick="btn_hledani_Click"></asp:LinkButton>
...
</asp:Panel>



Postedby tomino | 24 Comments    
Vedeno pod: , ,
Jak udělat (převést tabulku) Oracle SQL Developer --> Enterprise Architect
23 října 07 01:24 odp.
Co dělat v případě, že máme nějakou starou DB v Oracle a potřebujeme dostat část jejího schéma (např. pár tabulek) do fyzickeho modelu budoucí databáze, konkrétně do modelu tvořeném v Enterprise Architectovi?

Oracle SQL Developer -> Tools -> Export DDL ( and Data ),
v Options vybrat cilovy soubor s SQL skriptem,
přepnout na Objects -> All -> All My Objects -> Table
a vybrat tabulky, které je potřeba dodat do Enterprise Architectu.

V M$ SQL Management studiu vytvořit nějakou dočasnou databázi a otevřít vytvořený SQL skript. 
Následně upravovat nesrovnalosti mezi Oracle SQL a M$ SQL (tzn. Ctrl + H a opravovat do té doby,
než to půjde spustit Big Smile ) 

Nyní máme vytvořených pár tabulek, které trochu odpovídají těm v Oracle DB pěkně v M$ DB.

Vytvoříme ODBC zdroj dat k oné databázi.

V Enterprise Architectu kliknout pravým někam do diagramu a zvolit Import DB Schema from ODBC source.
Zvolíme vytvořený zdroj dat, dáme Import a ze seznamu vybereme tabulky, které chceme do diagramu přidat.
Potvrdíme a dopřejeme si dobrý pocit z toho, že jsme zase něco nemuseli dělat ručně ( i když možná utrpěla
produktivita práce Angel )


Postedby tomino | 4 Comments    
SQLXMLBulkLoad4Class chyba: Check the ErrorCode property of the exception to determine the HRESULT returned by the COM object
01 října 07 01:17 odp.
Check the ErrorCode property of the exception to determine the HRESULT returned by the COM object

System.Runtime.InteropServices.COMException was unhandled
Message="The statement has been terminated."
Source="Microsoft OLE DB Provider for SQL Server"
ErrorCode=-2147467259
StackTrace:
at SQLXMLBULKLOADLib.SQLXMLBulkLoad4Class.Execute(String bstrSchemaFile, Object vDataFile)
at DAT_DataImport.Program.exportXML2MsSQLDB(XElement XElem)  etc…

Tato „hodně vypovídající“ chyba vzniká, pokud se snažíme do tabulky vložit duplicitní klíčový atribut. Řešení je jednoduché... udělat si pořádek v tom, co se kdy vkládá. Geeked
Případně promáznout tabulku před vkládáním.

Postedby tomino | 0 Comments    
Vedeno pod: , ,
SQLXMLBULKLOADLib: Chyba &quot;Neplatn&#225; hodnota znaku pro určen&#237; převodu (CAST).&quot;
24 září 07 10:01 dop.
Kompletni zneni vyjimky:

System.Runtime.InteropServices.COMException was caught
Message="Neplatná hodnota znaku pro určení převodu (CAST)."
Source="Microsoft OLE DB Provider for SQL Server"
ErrorCode=-2147467259
StackTrace:
at SQLXMLBULKLOADLib.SQLXMLBulkLoad4Class.Execute(String bstrSchemaFile, Object vDataFile)
at VIP_DataImport.Program.Main(String[] args) in C:\PUBLIC\WORK_SVN\NSP\VIP_DataImport\Program.cs:line 29
InnerException:

Tato chyba nastává při pokusu o BulkLoad při použití SQLXMLBulkLoad4Class. Pokud jsou ve vstupním XML např. data vyexportovana z Oracle, tak každá hodnota elementu je uložena takto: "<![CDATA[hodnota_elementu]]>". Problém nastává, pokud je honota null, tj. uložena takto <![CDATA[]]>. Řešení je jednoduché... odstranit <![CDATA[]]> z celého dokumentu.

Tato chyba může rovněž nastat, pokud máme v příslušném .xsd schéma špatně uveden datový typ v atributu "Type". Např. při vkládání do tabulky, která má atribut typu varchar a atribut "Type" v elementu <xsd:element Type="xsd:integer"> v .xsd souboru má uvedený typ nastaveny jako integer.
Postedby tomino | 4 Comments    
Vedeno pod: , ,
Import dat do MS Sql DB z XML pomoc&#237; SQLXML Bulkload
21 září 07 09:39 dop.
Nejtěžší věc na všem je najit onu knihovnu, která to ma všechno na svědomí. Mělo by to být pod SQLXML 4.0, ale M$ se asi zřejmě snaží udělat v tom co největší bordel Ick! Z netu se dá stáhnout tak možna verze 3.0 SP 3, ale proc ji používat, když existuje novějši. 
Verze 3.0 se dá najít přímo při přidávání reference pod COM / Microsoft SQLXML Bulkload 3.0 Type Library. 
Pro verzi 4.0 se musí natvrdo přidat soubor C:\Program Files\Common Files\System\Ole DB\sqlxml4.dll.

přidá se namespace:
using SQLXMLBULKLOADLib;


kod programu muze vypadat nasledovne:
namespace MyDataImport {
class Program {
  [STAThread]
  static void Main(string[] args) {
    try
    {
      string myConnectionString = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
      SQLXMLBulkLoad4Class bulkLoad = new SQLXMLBulkLoad4Class();       bulkLoad.ConnectionString = myConnectionString; bulkLoad.XMLFragment = true;       bulkLoad.KeepIdentity = true; bulkLoad.ErrorLogFile = "error.xml";       bulkLoad.Execute("Data/mojeSchema.xsd", "Data/mojeData.xml");
    } catch(Exception e)
    {
      Console.WriteLine(e.ToString());
    }
  }
}
}


Takto muze vypadat uzity XML soubor:
<?xml version="1.0"?>
  <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <tabulka>
    <IDCISOBORY><![CDATA[1]]></IDCISOBORY>
    <NAZEV><![CDATA[nejaky nazev 1]]></NAZEV>
    <SOUKROME>5</SOUKROME>
  </tabulka>
  <tabulka>
    <IDCISOBORY><![CDATA[2]]></IDCISOBORY>
    <NAZEV><![CDATA[nejaky nazev 2]]></NAZEV>
    <SOUKROME></SOUKROME>
</tabulka>
</ROOT>

A takto muze vypadat potrebne schema:
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
<xsd:element name="tabulka" sql:relation="JmenoTabulkyDB" >
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="IDCISOBORY" sql:field="id_Obory_v_DB" type="xsd:integer" />
      <xsd:element name="NAZEV" sql:field="nazev_v_DB" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>
</xsd:schema>

Schválně uvádím příklad, kde všechno "nesedí" na všechno, protože příliš přesné příklady, kde všechno krásně vychází se v praxi moc nevyskytují.

Toto použití dané knihovný přináší kromě nesporně velkého přínosu v rychlosti kopírování dat také nevyhodu nepříjemného ladění vzhledem ke špatně popisujícím chybam, které se mohou vyskytnout. Doporučuju proto případně mrknou na řešení chyby Neplatná hodnota znaku pro určení převodu (CAST)".

Postedby tomino | 20 Comments    
Vedeno pod: , ,
Jak na spuštění (SQL skriptu v souboru) v jiném SQL skriptu
21 září 07 08:45 dop.
Řešení je jednoduché:

1) vložit do skriptu řádek s cestou k souboru (to :r na začátku je důležité)

:r C:\CESTA_K_SOUBORU\mujSqlSkript.SQL

Nastavit v horním menu: Query -> SQLCMD Mode
Postedby tomino | 26 Comments    
Vedeno pod:
Vyvojar.cz na prodej!