<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.nils-andresen.de/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" gd:etag="W/&quot;DkICRH4_cSp7ImA9WhRaFEk.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497</id><updated>2012-02-16T18:09:25.049-08:00</updated><category term="CCD" /><category term="Python" /><category term="outlook" /><category term="Nautilus" /><category term="winforms" /><category term="SQL" /><category term="cygwin" /><category term="generics" /><category term="wpf" /><category term="EntityFramework" /><category term="WindowsShellExtension" /><category term="vs2008" /><category term="Autovervollständigung" /><category term="mono" /><category term="word" /><category term="nunit" /><category term="bash" /><category term="mercurial" /><category term="neo-layout" /><category term="backup" /><category term="unity" /><category term="finalbuilder" /><category term="Projekte" /><title>Nils Andresen</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>38</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.nils-andresen.de/NilsAndresen" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="nilsandresen" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;A04CSX09eip7ImA9WhZaE0k.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-4747000422236160055</id><published>2011-06-08T23:53:00.000-07:00</published><updated>2011-06-29T05:19:28.362-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-29T05:19:28.362-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mercurial" /><category scheme="http://www.blogger.com/atom/ns#" term="finalbuilder" /><title>Finalbuilder-Hook in Mercurial</title><content type="html">In der Firma in der ich arbeite wird viel &lt;a href="http://www.finalbuilder.com/home.aspx"&gt;Finalbuilder &lt;/a&gt;verwendet. Das Tool ist zwar ganz nett, hat aber Probleme zu bemerken dass eine bereits geöffnete Datei verändert wurde. Das führt zu den merkwürdigsten Problemen wenn die Finalbuilder-Dateien unter Versionskontrolle stehen (Schnell ein update machen, aber Finalbuilder ist noch geöffnet. Das update funktioniert problemlos, nur sind keine Änderungen im Finalbuilder „angekommen“)&lt;br /&gt;
&lt;br /&gt;
Damit mir das nicht mehr passiert habe ich mir mal einen kleinen hook für &lt;a href="http://mercurial.selenic.com/"&gt;mercurial &lt;/a&gt;zusammen gezimmert.&lt;br /&gt;
&lt;br /&gt;
Einfach das folgende Skript irgendwo auf der Platte parken:&lt;br /&gt;
&lt;pre class="brush: python"&gt;#!/usr/bin/python
# -*- coding: utf-8 -*-
import os

def preupdate(ui, repo, **kwargs):
 basepath = repo.origroot
 rev = kwargs['parent1']
 node = repo.changelog.lookup(rev)
 _,_,_,files,_,_ = repo.changelog.read(node)
 for file in files:
  if os.path.splitext(file)[1] != '.fbz6':
   continue
  fb_file = os.path.join(basepath, file)
  fb_lockfile = os.path.splitext(fb_file)[0] + '.fb6lck'
  if os.path.exists(fb_lockfile):
   ui.write('Fehler: Die Finalbuilder-Datei\n%s\nsoll geändert werden, ist aber noch gelockt.\nSchließen sie Finalbuilder um das Update durchzuführen.\n' % fb_file)
   ui.write('(Hinweis: Wenn sie (wirklich...) keinen Finalbuilder mehr geöffnet haben,\nsollten sie die lock-datei löschen.\n diese findet sich unter:\n%s)\n' % fb_lockfile)
   return True
 
 return False
&lt;/pre&gt;&lt;br /&gt;
Diesen hook dann noch in mercurial einbauen, indem die globale mercurial.ini (bei mir: c:\users\nils\mercurial.ini) mit einem editor geöffnet wird und folgende Zeilen ergänzen:&lt;br /&gt;
&lt;pre class="brush: shell"&gt;[hooks]
preupdate.finalbuilder = python:C:\wo\das\skript\liegt.py:preupdate
&lt;/pre&gt;&lt;br /&gt;
Mehr info's über mercurial-hooks gib es im &lt;a href="http://hgbook.red-bean.com/read/handling-repository-events-with-hooks.html"&gt;mercurial Buch, Kap. 10&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Zur Ausführung dieses hooks muss kein python extra installiert werden, der hook wird einfach „direkt“ in mercurial ausgeführt. Mehr dazu gibt es im &lt;a href="http://hgbook.red-bean.com/read/handling-repository-events-with-hooks.html#sec:hook:ref"&gt;mercurial Buch&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-4747000422236160055?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/4747000422236160055/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2011/06/finalbuilder-hook-in-mercurial.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/4747000422236160055?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/4747000422236160055?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2011/06/finalbuilder-hook-in-mercurial.html" title="Finalbuilder-Hook in Mercurial" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;Ck4CRXY_eSp7ImA9WhZVFks.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-580011963884783167</id><published>2011-05-29T02:21:00.000-07:00</published><updated>2011-05-29T02:22:44.841-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-29T02:22:44.841-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Nautilus" /><title>Pfadleiste in Nautilus 3 - oder wo ist mein „überliegendes Verzeichnis“-Knopf geblieben…</title><content type="html">&lt;div&gt;Ich habe gestern auf gnome 3 umgestellt, daher ist meine aktuelle Version von Nautilus die v. 3.0.1.1&lt;br /&gt;
Nun fehlt in dieser der Knopf für „überliegendes Verzeichnis“. Klar - der „Zurück“-Knopf führt in wohl 80% der Fälle zum überliegenden Verzeichnis... Ich vermisse ihn aber trotzdem.&lt;br /&gt;
Eine kleine Suche hat mich auf die Antwort gebracht: Der&amp;nbsp;„überliegendes Verzeichnis“-Knopf ist nicht mehr notwendig, die Verzeichnis-Anzeige ist ja in der „Pfadleiste“ - und da kann man ja einfach das überliegende Verzeichnis anklicken...&amp;nbsp;Achso? Nicht bei mir...&lt;br /&gt;
Bei mir ist keine Pfadleiste, sondern ein Text-Feld....&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-07d37J1QoHM/TeIKZkJCBLI/AAAAAAAAAak/gVP5hfYcSYs/s1600/nautilus-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="280" src="http://1.bp.blogspot.com/-07d37J1QoHM/TeIKZkJCBLI/AAAAAAAAAak/gVP5hfYcSYs/s400/nautilus-1.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Es hat etwas länger gedauert bis ich heraus gefunden hatte, dass Nautilus die Pfadleiste ja schon lange hatte, nur halt nicht bei mir - und nach reichlich nachdenken bin ich mir ganz sicher — die Pfadleiste hatte ich mal abgeschaltet.&amp;nbsp;Aber wie nun wieder zurück bekommen?&lt;br /&gt;
Die Lösung liegt in der &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;always-use-location-entry&lt;/span&gt;&amp;nbsp;Einstellung von Nautilus.&lt;br /&gt;
Also den dconf-editor geöffnet und navigieren nach org/gnome/nautilus/preferences:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-I1QGX7INs0k/TeIMgcl_SdI/AAAAAAAAAao/ycNnDsLSY0M/s1600/dconf.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="315" src="http://2.bp.blogspot.com/-I1QGX7INs0k/TeIMgcl_SdI/AAAAAAAAAao/ycNnDsLSY0M/s400/dconf.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;Nachdem ich die Einstellung zurück gesetzt habe erscheint auch die&amp;nbsp;Pfadleiste:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-uEXeLXaBvlk/TeIOuhb2E3I/AAAAAAAAAas/fPDpqdTWhg0/s1600/nautilus-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="280" src="http://3.bp.blogspot.com/-uEXeLXaBvlk/TeIOuhb2E3I/AAAAAAAAAas/fPDpqdTWhg0/s400/nautilus-2.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;Super. Das Textfeld, dass ich vorher hatte kann jetzt übrigens temporär aktiviert werden über Strg+L oder „Gehe zu“&amp;gt;„Ort”&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-580011963884783167?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/580011963884783167/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2011/05/pfadleiste-in-nautilus-3-oder-wo-ist.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/580011963884783167?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/580011963884783167?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2011/05/pfadleiste-in-nautilus-3-oder-wo-ist.html" title="Pfadleiste in Nautilus 3 - oder wo ist mein „überliegendes Verzeichnis“-Knopf geblieben…" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-07d37J1QoHM/TeIKZkJCBLI/AAAAAAAAAak/gVP5hfYcSYs/s72-c/nautilus-1.png" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CkEAQn84fyp7ImA9WhZQFEs.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-4149624358883826894</id><published>2011-04-22T01:24:00.000-07:00</published><updated>2011-04-22T01:24:03.137-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-22T01:24:03.137-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CCD" /><category scheme="http://www.blogger.com/atom/ns#" term="mono" /><category scheme="http://www.blogger.com/atom/ns#" term="Nautilus" /><title>Leere VS2010 Solution in Nautilus</title><content type="html">Ich habe schon einmal geschrieben, &lt;a href="http://blog.nils-andresen.de/2009/06/leere-visual.html"&gt;wie man eine neue VS2008 Solution mit dem Explorer anlegen kann&lt;/a&gt;.&lt;br /&gt;
Das selbe ist natürlich auch für gnomes Nautilus möglch.&lt;br /&gt;
Einfach eine der Vorlagen (&lt;a href="https://sites.google.com/site/andresennils/sonstiges/leeresolutionerstellen/VisualStudio2008Solution.sln?attredirects=0&amp;amp;d=1"&gt;2008&lt;/a&gt; oder &lt;a href="https://sites.google.com/site/andresennils/sonstiges/leeresolutionerstellen/VisualStudio2010Solution.sln?attredirects=0&amp;amp;d=1"&gt;2010&lt;/a&gt;) ablegen im Template-Verzeichnis ablegen und mit &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;"nautilus -q"&lt;/span&gt; Nautilus neu starten.&lt;br /&gt;
&lt;br /&gt;
Das Template-Verzeichnis von Nautilus ist unter dem Namen &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;XDG_TEMPLATES_DIR&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt; abgelegt in der Datei user-dirs.dirs des config-verzeichnisses. Dieses sollte in&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;XDG_CONFIG_HOME&lt;/span&gt;&amp;nbsp;stehen, standard ist &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;~./config&lt;/span&gt;.&lt;br /&gt;
Also im&amp;nbsp;Lieblings-Editor (vim für mich...)&amp;nbsp;die user-dirs.dir bearbeiten :&lt;br /&gt;
&lt;pre class="brush: shell"&gt;vim ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs
&lt;/pre&gt;&lt;br /&gt;
und entweder herausfinden was der Wert der variablen ist, oder einen guten setzen. Meiner ist:&lt;br /&gt;
&lt;pre class="brush: shell"&gt;XDG_TEMPLATES_DIR="$HOME/.XdgTemplates"
&lt;/pre&gt;&lt;br /&gt;
Also&amp;nbsp;Kurzfassung:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt;XDG_TEMPLATES_DIR&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt; finden&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;Vorlage (&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;&lt;a href="https://sites.google.com/site/andresennils/sonstiges/leeresolutionerstellen/VisualStudio2008Solution.sln?attredirects=0&amp;amp;d=1"&gt;2008&lt;/a&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;oder&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;&lt;a href="https://sites.google.com/site/andresennils/sonstiges/leeresolutionerstellen/VisualStudio2010Solution.sln?attredirects=0&amp;amp;d=1"&gt;2010&lt;/a&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;) im&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt;XDG_TEMPLATES_DIR&lt;/span&gt;&amp;nbsp;ablegen&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Nautilus neustarten (&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;nautilus -q)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-4149624358883826894?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/4149624358883826894/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2011/04/leere-vs2010-solution-in-nautilus.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/4149624358883826894?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/4149624358883826894?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2011/04/leere-vs2010-solution-in-nautilus.html" title="Leere VS2010 Solution in Nautilus" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0IGSHcyfSp7ImA9WhZQGEw.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-2108566805088121008</id><published>2011-04-22T01:11:00.000-07:00</published><updated>2011-04-26T05:05:29.995-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-26T05:05:29.995-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="cygwin" /><title>vim probleme mit delete unter rxvt?</title><content type="html">In meinem &lt;a href="http://blog.nils-andresen.de/2011/04/besserer-terminal-emulator-fur-cygwin.html"&gt;letzten post&lt;/a&gt; hatte ich dargestellt, wie man einen netten terminal-emulator (rxvt) unter cygwin zum laufen bringt. Soweit so gut.&lt;br /&gt;
Jetzt machte aber plötzlich mein vim probleme: Del funktionierte manchmal nicht und die Pfeiltasten verhielten sich auch komisch..&lt;br /&gt;
Die Antwort war wie immer recht einfach: Ich hatte die .vimrc vergessen.&lt;br /&gt;
&lt;pre class="brush: shell"&gt;cp /usr/share/vim/vim73/vimrc_example.vim ~/.vimrc
&lt;/pre&gt;Behebt das Problem. Super-Einfache lösung.&lt;br /&gt;
(Nur vorsicht, wenn man schon eine .vimrc hat...)&lt;br /&gt;
&lt;br /&gt;
EDIT:&lt;br /&gt;
Natürlich ist es nicht „die magische .vimrc“, die das Problem behebt, sondern die folgende Zeile innerhalb dieser:&lt;br /&gt;
&lt;pre class="brush: shell"&gt;set backspace=indent,eol,start
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-2108566805088121008?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/2108566805088121008/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2011/04/vim-probleme-mit-delete-unter-rxvt.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/2108566805088121008?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/2108566805088121008?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2011/04/vim-probleme-mit-delete-unter-rxvt.html" title="vim probleme mit delete unter rxvt?" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;AkMNQ306eSp7ImA9WhZQFEg.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-6401138909197095144</id><published>2011-04-22T00:48:00.000-07:00</published><updated>2011-04-22T00:48:12.311-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-22T00:48:12.311-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="cygwin" /><title>Besserer Terminal-Emulator für cygwin</title><content type="html">Seit kurzem befasse ich mich (mal wieder) mit &lt;a href="http://www.cygwin.com/"&gt;cygwin&lt;/a&gt;. Eine gute Idee habe ich heute im Netz gefunden: Den bestehenden emulator gegen &lt;a href="http://rxvt.net/"&gt;rxvt&lt;/a&gt;&amp;nbsp;ersetzen.&lt;br /&gt;
Dafür muss natürlich rxvt in der cygwin-umgebung installiert sein.&lt;br /&gt;
Folgende bat-Datei sollte dann zum starten erstellt werden:&lt;br /&gt;
&lt;pre class="brush: shell"&gt;@echo off
C:
chdir C:\cygwin\bin
start rxvt -sr -sl 10000 -fg white -bg black -fn "Lucida Console-10" -tn cygwin -e /bin/bash --login -i
&lt;/pre&gt;&lt;br /&gt;
Super.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-6401138909197095144?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/6401138909197095144/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2011/04/besserer-terminal-emulator-fur-cygwin.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/6401138909197095144?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/6401138909197095144?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2011/04/besserer-terminal-emulator-fur-cygwin.html" title="Besserer Terminal-Emulator für cygwin" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0YBSHY9fSp7ImA9WhZTGEQ.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-8195141128996453609</id><published>2011-03-23T07:39:00.000-07:00</published><updated>2011-03-23T07:39:19.865-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-23T07:39:19.865-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="word" /><title>Word-Dokumente zusammenfassen</title><content type="html">Mein aktuelles Problem: Mehrere Word-Dokumente sollten in einem neuem Dokument zusammengefasst werden.&lt;br /&gt;
&lt;br /&gt;
Zwei mögliche Lösungen bieten sich an:&lt;br /&gt;
1. Neues Word-Dokument erstellen, Einfügen, Objekt, „Text aus Datei”&lt;br /&gt;
2. Ein Makro erstellen, dass alle Dateien in einem bestimmten Ordner öffnet und in eine neue Datei einfügt (ohne Beachtung einer eventuell gewünschten Reihenfolge).&lt;br /&gt;
&lt;br /&gt;
Da mir Variante 2 besser gefällt (*grins*) folgt der verwendete code:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: vb"&gt;Sub ConcatenateAllWordFiles()
 Dim mypath
 mypath = BrowseFolder("Verzeichnis Wählen")
 
 Set fso = CreateObject("Scripting.FileSystemObject")
 Set Folder = fso.GetFolder(mypath)
 Set allFiles = Folder.Files
 Set newDoc = Documents.Add

 For Each file In allFiles
    If Right(file, 5) = ".docx" Then

        Documents.Open FileName:=file.Path
        current = ActiveDocument.Name
        Selection.WholeStory
        Selection.Copy
        Documents(current).Close
        newDoc.Activate
        Selection.Paste
        Selection.EndKey Unit:=wdLine
    End If
 Next
End Sub

Function BrowseFolder(Title As String, _
        Optional InitialFolder As String = vbNullString, _
        Optional InitialView As Office.MsoFileDialogView = _
            msoFileDialogViewList) As String
    Dim V As Variant
    Dim InitFolder As String
    With Application.FileDialog(msoFileDialogFolderPicker)
        .Title = Title
        .InitialView = InitialView
        If Len(InitialFolder) &amp;gt; 0 Then
            If Dir(InitialFolder, vbDirectory) &amp;lt;&amp;gt; vbNullString Then
                InitFolder = InitialFolder
                If Right(InitFolder, 1) &amp;lt;&amp;gt; "\" Then
                    InitFolder = InitFolder &amp;amp; "\"
                End If
                .InitialFileName = InitFolder
            End If
        End If
        .Show
        On Error Resume Next
        Err.Clear
        V = .SelectedItems(1)
        If Err.Number &amp;lt;&amp;gt; 0 Then
            V = vbNullString
        End If
    End With
    BrowseFolder = CStr(V)
End Function
&lt;/pre&gt;&lt;br /&gt;
Das ist natürlich nicht alles meine alleinige Idee, die Grobe Vorlage war &lt;a href="http://ask.metafilter.com/17246/Making-One-Document-from-Many-in-Microsoft-Word"&gt;dies&lt;/a&gt;.&lt;br /&gt;
Wie BrowseFolder-Funktion habe ich komplett „gefunden”...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-8195141128996453609?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/8195141128996453609/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2011/03/word-dokumente-zusammenfassen.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/8195141128996453609?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/8195141128996453609?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2011/03/word-dokumente-zusammenfassen.html" title="Word-Dokumente zusammenfassen" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0cFRXcyfyp7ImA9WxFaGUU.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-6848077303252936</id><published>2010-07-24T09:28:00.000-07:00</published><updated>2010-07-24T09:30:14.997-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-24T09:30:14.997-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="Nautilus" /><title>Nautilus-Erweiterung mit Python</title><content type="html">Heute gab es bei mir ja schon eine &lt;a href="http://blog.nils-andresen.de/2010/07/explorer-erweiterung-shell-extension.html"&gt;Explorer-Erweiterung mit Python&lt;/a&gt;. Das gleiche benötige ich auch am heimischen Rechner - nur unter Nautilus:&lt;br /&gt;
&lt;pre class="brush:python"&gt;#!/usr/bin/python
# -*- coding: utf-8 -*-

import urllib
import easygui
import logging
import nautilus
import os

CCDFOLDERS =  [
 'source',
 'bin',
 'build',
 'lib',
 'resource',
 ]

class CcdDirStructureExtension(nautilus.MenuProvider):

 def __init__(self):
  pass
 
 
 def _alertError(self, message):
  easygui.msgbox(message, title='Alert', ok_button='Mist!')
 
 
 def _create_ccd_structure(self, foldername):
  ok = easygui.ynbox(msg=u'wirklich eine CCD-Struktur ersellen in\n' + foldername,
   title=u'Erstellen bestägen', choices=('Ja, bitte', 'Nein, danke'))
  if ok == 0:
   return

  if  not os.path.isdir(foldername):
   self._alertError(foldername + u'\nist kein Verzeichnis. Abgebrochen.')
   return

  try:
   for ccd in CCDFOLDERS:
    dir = os.path.join(foldername, ccd)
    os.mkdir(dir)
  except Exception, e:
   self._alertError(e)
   raise
 
 
 def menu_activate(self, menu, file):
  """Called when the user selects the menu."""
  filename = urllib.unquote(file.get_uri()[7:])
  self._create_ccd_structure(filename)


 def get_file_items(self, window, files):
  """Called when the user selects a file in Nautilus."""  
  if len(files) != 1:
   return
   
  file = files[0]
  if not file.is_directory() or file.get_uri_scheme() != 'file':
   return

  return self._get_MenuItemForFile(file)
  

 def get_background_items(self, window, file):
  """Called when the user clicks the background of a Nautilus-Window"""
  if not file.is_directory() or file.get_uri_scheme() != 'file':
   return
  return self._get_MenuItemForFile(file)


 def _get_MenuItemForFile(self, file):
  item = nautilus.MenuItem("NautilusPython::ccd-dir::create",
   "CCD-Struktur", 
   "erstellt eine CCD-Verzeichnisstruktur in %s" % file.get_name())
  item.connect("activate", self.menu_activate, file)
  return item,


if __name__ == '__main__':
 print 'This is a Nautilus extenion. Copy it to ${HOME}/.nautilus/python-extensions/ and restart Nautilus. Have fun.'
&lt;/pre&gt;Der Code gehört bei Installierten Nautilus-Python-Bindings nach ${HOME}/.nautilus/python‑extensions/ und sollte ausführbar sein (chmod 755).&lt;br /&gt;
Die Dialoge werden von &lt;a href="http://easygui.sourceforge.net/"&gt;EasyGui&lt;/a&gt; erstellt, irgendwie gab es &lt;a href="http://stackoverflow.com/questions/3325772/use-gtk-in-a-nautilus-extension-using-python"&gt;Probleme gtk-Dialoge zu erzeugen&lt;/a&gt;...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-6848077303252936?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/6848077303252936/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2010/07/nautilus-erweiterung-mit-python.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/6848077303252936?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/6848077303252936?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2010/07/nautilus-erweiterung-mit-python.html" title="Nautilus-Erweiterung mit Python" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;Dk4EQnc7fSp7ImA9Wx5TE0w.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-845835902694918973</id><published>2010-07-24T03:25:00.000-07:00</published><updated>2010-07-28T04:01:43.905-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-28T04:01:43.905-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CCD" /><category scheme="http://www.blogger.com/atom/ns#" term="WindowsShellExtension" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><title>Explorer-Erweiterung (shell extension) mit Python</title><content type="html">Die Problemstellung: Eine Verzeichnisstruktur soll automatisch erstellt werden, und zwar über einen Eintrag im Context-Menü des Explorers.&lt;br /&gt;
Die ganze Vorgeschichte ist &lt;a href="http://blog.nils-andresen.de/2010/07/ccd-projekt-verzeichnisstruktur.html"&gt;hier&lt;/a&gt;.&lt;br /&gt;
Nun die Lösung in Python. Das ganze ist recht übersichtlich:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:python"&gt;# -*- coding: utf-8 -*-

#   Erstellt einen Eintrag im Context-Menü des Explorers: CCD-Verzeichnis erstellen
#   bei Click wird im gewählten Verzeichnis eine CCD-Verzeichnisstrukur
#   (bin, build, lib, source, resources) erstellt.

import os.path
import pythoncom
from win32com.shell import shell, shellcon
import win32gui
import win32con

IContextMenu_Methods = ["QueryContextMenu", "InvokeCommand", "GetCommandString"]
IShellExtInit_Methods = ["Initialize"]

#   HKCR Key   Affected object types
#      *    All files
#AllFileSystemObjects  All regular files and file folders
#     Folder   All folders, virtual and filesystem
#     Directory   File folders
#Directory\Background  Directory-Background (Folder is open, one clicks on the white background...)
#      Drive   Root folders of all system drives
#    Network   Entire network
#   NetShare   All network shares

TYPES = [
 'Directory\\Background',
 'Directory',
 ]
SUBKEY = 'CCD-Verzeichnis'

CCDFOLDERS = [
 'source',
 'bin',
 'build',
 'lib',
 'resource',
 ]

def alertError(hwnd, exc):
 win32gui.MessageBox(hwnd, str(exc), str(exc.__class__), win32con.MB_OK)


class ShellExtension:
 _reg_progid_ = "CCD.Verzeichnisersteller.ShellExtension.ContextMenu"
 _reg_desc_ = "CCD-Verzeichnis Shell Extension (context menu)"
 _reg_clsid_ = "{5C664DC4-5ADA-4385-9DEB-EDB51320A668}"

 _com_interfaces_ = [shell.IID_IShellExtInit, shell.IID_IContextMenu]
 _public_methods_ = IContextMenu_Methods + IShellExtInit_Methods

 def Initialize(self, folder, dataobj, hkey):
  self.dataobj = dataobj

 def QueryContextMenu(self, hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags):
  try:
   msg = 'CCD-Verzeichnis ersellen'

   idCmd = idCmdFirst
   items = []
   if (uFlags &amp;amp;amp; 0x000F) == shellcon.CMF_NORMAL:
    items.append(msg)
   elif uFlags &amp;amp;amp; shellcon.CMF_VERBSONLY:
    items.append(msg)
   elif uFlags &amp;amp;amp; shellcon.CMF_EXPLORE:
    items.append(msg)
   else:
    pass
    
   win32gui.InsertMenu(hMenu, indexMenu,
        win32con.MF_SEPARATOR|win32con.MF_BYPOSITION,
        0, None)
   indexMenu += 1
   for item in items:
    win32gui.InsertMenu(hMenu, indexMenu,
         win32con.MF_STRING|win32con.MF_BYPOSITION,
         idCmd, item)
    indexMenu += 1
    idCmd += 1

   win32gui.InsertMenu(hMenu, indexMenu,
        win32con.MF_SEPARATOR|win32con.MF_BYPOSITION,
        0, None)
   indexMenu += 1
   return idCmd-idCmdFirst

  except Exception, e:
   alertError(None, e)
   raise


 def InvokeCommand(self, ci):
  mask, hwnd, verb, params, dir, nShow, hotkey, hicon = ci
  
  try:
   if self.dataobj is None:
    #background-click
    fname = dir
   else:
    #get Files from dragObject
    files = self.getDragFiles()
    if not files:
     return
    fname = files[0]

   self.CreateCCDFolderStructure(hwnd, fname)
  except Exception, e:
   alertError(hwnd, e)
   raise
  return


 def GetCommandString(self, cmd, typ):
  return "Erstellt eine CCD-Verzeichnisstruktur"


 def getDragFiles(self):
  # Format the DataObject using a formatec, then get DragQueryFile from it...
  format_etc = win32con.CF_HDROP, None, 1, -1, pythoncom.TYMED_HGLOBAL
  sm = self.dataobj.GetData(format_etc)
  num_files = shell.DragQueryFile(sm.data_handle, -1)
  files = [shell.DragQueryFile(sm.data_handle, i) for i in range(num_files)]
  return files
  
  
 def CreateCCDFolderStructure(self, hwnd, folder):
  ok = win32gui.MessageBox(hwnd, u'wirklich eine CCD-Struktur ersellen in\n' + folder,
   u'Erstellen bestägen', 
   win32con.MB_YESNO|win32con.MB_ICONQUESTION|win32con.MB_TASKMODAL|win32con.MB_SETFOREGROUND)
  if ok != win32con.IDYES:
   return
  
  if not os.path.isdir(folder):
   alertError(hwnd, folder + u'\nist kein Verzeichnis. Abgebrochen.')
  
  try:
   for ccd in CCDFOLDERS:
    dir = os.path.join(folder, ccd)
    os.mkdir(dir)
  except Exception, e:
   alertError(hwnd, e)
   raise
  return 

def DllRegisterServer():
 import _winreg
 for typ in TYPES:
  key = _winreg.CreateKey(_winreg.HKEY_CLASSES_ROOT, "%s\\shellex" % typ)
  subkey = _winreg.CreateKey(key, "ContextMenuHandlers")
  subkey2 = _winreg.CreateKey(subkey, SUBKEY)
  _winreg.SetValueEx(subkey2, None, 0, _winreg.REG_SZ, ShellExtension._reg_clsid_)
 print ShellExtension._reg_desc_, "registration complete."


def DllUnregisterServer():
 import _winreg
 for typ in TYPES:
  try:
   key = _winreg.DeleteKey(_winreg.HKEY_CLASSES_ROOT, "%s\\shellex\\ContextMenuHandlers\\%s" % (typ, SUBKEY))
  except WindowsError, details:
   import errno
   if details.errno != errno.ENOENT:
    raise
 print ShellExtension._reg_desc_, "unregistration complete."

 
def main(argv):
 from win32com.server import register
 register.UseCommandLine(ShellExtension,
       finalize_register = DllRegisterServer,
       finalize_unregister = DllUnregisterServer)

if __name__=='__main__':
 import sys
 main(sys.argv)
&lt;/pre&gt;&lt;br /&gt;
Für die Verwendung muss &lt;a href="http://python.org/"&gt;Python&lt;/a&gt; installiert sein (&lt;a href="http://python.org/download/releases/2.6.5/"&gt;Empfehlung: 2.6&lt;/a&gt;) und passend zu der Python-Version &lt;a href="http://sourceforge.net/projects/pywin32/"&gt;PyWin32&lt;/a&gt; (&lt;a href="http://sourceforge.net/projects/pywin32/files/"&gt;Empfehlung: 214.win32-py2.6&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
Die Python-Datei in ein „kluges“ Verzeichnis legen (z.B. %ProgramFiles%\ccd‑verzeichnis\) und in der registry registrieren per doppelklick, oder über die Eingabeaufforderung mit &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ccd-verzeichnis.py --register&lt;/span&gt;. Wenn das ganze wieder entfernt werden soll, so geht dies nur über die Eingabeaufforderung mit &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ccd-verzeichnis.py --unregister&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Viel Spass.&lt;br /&gt;
&lt;br /&gt;
Edits:&lt;br /&gt;
- Das ganze gibt's natürlich auch als &lt;a href="http://blog.nils-andresen.de/2010/07/nautilus-erweiterung-mit-python.html"&gt;Nautilus-Erweiterung&lt;/a&gt;...&lt;br /&gt;
- Vorlage für den Code war eine &lt;a href="http://pywin32.cvs.sourceforge.net/viewvc/pywin32/pywin32/com/win32comext/shell/demos/servers/context_menu.py?view=markup&amp;amp;pathrev=HEAD"&gt;Beispiel-Anwendung des PyWin32-Projektes&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-845835902694918973?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/845835902694918973/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2010/07/explorer-erweiterung-shell-extension.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/845835902694918973?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/845835902694918973?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2010/07/explorer-erweiterung-shell-extension.html" title="Explorer-Erweiterung (shell extension) mit Python" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;Ck8CSH88fyp7ImA9WxFaGUU.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-5746877379175156194</id><published>2010-07-24T03:07:00.000-07:00</published><updated>2010-07-24T07:14:29.177-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-24T07:14:29.177-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CCD" /><title>CCD-Projekt Verzeichnisstruktur automatisiert erstellen</title><content type="html">Im „Clean Code Developer Camp“ bekam ich die Empfehlung, dass die Verzeichnisstruktur in einem Projekt (Entwicklungsverzeichnisse, keine Abrechnungen, Verträge oder so...) einheitlich sein sollte. Die Empfehlung war unter dem Toplevel die Folgenden Unterverzeichnisse:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;bin - Alles, was erstellt wird (start.exe, ergänzung.dll, …) landet hier.&lt;/li&gt;
&lt;li&gt;build - Hier findet sich das Buildskript um das Projekt komplett zu bauen&lt;/li&gt;
&lt;li&gt;lib - 3rd-Party-Tools finden sich hier.&lt;/li&gt;
&lt;li&gt;resources - Hier findet sich alles, was sonst noch benötigt wird um das fertige Projekt laufen zu lassen&lt;/li&gt;
&lt;li&gt;source - Die Sourcen...&lt;/li&gt;
&lt;/ul&gt;Da ich das Problem habe mir das nicht immer merken zu können und außerdem eine manuelle Anlage dieser Struktur immer Zeit kostet habe ich mir gedacht ich schreibe einfach mal eine Erweiterung für den Explorer, mit der Funktion diese Struktur in einem Verzeichnis zu erstellen.&lt;br /&gt;
&lt;br /&gt;
Für den durchschnittlichen nicht-c-Programmierer ist das aber alles andere als einfach habe ich herausfinden müssen. &amp;nbsp; &lt;br /&gt;
Meine Erste Idee war c#, mit P/Invoke... Das hat bisher nicht funktioniert wenn ich das zum Laufen bekomme, werde ich darüber berichten.&lt;br /&gt;
Der aktuelle Ansatz ist Python, mit PyWin32. &lt;a href="http://blog.nils-andresen.de/2010/07/explorer-erweiterung-shell-extension.html"&gt;Das scheint recht simpel&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-5746877379175156194?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/5746877379175156194/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2010/07/ccd-projekt-verzeichnisstruktur.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/5746877379175156194?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/5746877379175156194?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2010/07/ccd-projekt-verzeichnisstruktur.html" title="CCD-Projekt Verzeichnisstruktur automatisiert erstellen" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CE4MQHk9cCp7ImA9WxFaF0U.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-3980924232528398068</id><published>2010-07-22T00:16:00.000-07:00</published><updated>2010-07-22T00:16:21.768-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-22T00:16:21.768-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="bash" /><title>Dateinamen bereinigen</title><content type="html">Meine Problemstellung gerade: Diverse Dateien in diversen Unterverzeichnissen haben "komische" Dateinamen und lassen sich unter Windows nicht entpacken...&lt;br /&gt;
&lt;br /&gt;
Mein quick-Fix: Dateinamen bereinigen (natürlich unter Linux...) und alle nicht Standard Zeichen ersetzen.&lt;br /&gt;
In diesem Fall war es für mich ausreichend Buchstaben, Zahlen und den Punkt zu lassen, der Rest wurde durch Unterstriche ersetzt&lt;br /&gt;
&lt;br /&gt;
Dafür verwendete ich folgendes Skript:&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;find -depth -name "* *" | while read file; do
   filePath="$(dirname "${file}")"
   oldFileName="$(basename "${file}")"
   newFileName=${oldFileName//[^a-zA-Z0-9\.]/_}
   mv "${filePath}"/"${oldFileName}" "${filePath}"/"${newFileName}"
done
&lt;/pre&gt;&lt;br /&gt;
Das ganze hat nur noch ein kleines Problem: Es funktioniert nicht für Dateinamen mit Leerzeichen am Ende des Dateinamens - hier muss das Skript verbessert werden, oder manuell nachgearbeitet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-3980924232528398068?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/3980924232528398068/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2010/07/dateinamen-bereinigen.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/3980924232528398068?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/3980924232528398068?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2010/07/dateinamen-bereinigen.html" title="Dateinamen bereinigen" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CkIAQn89cSp7ImA9WxFaE0Q.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-4168200276061236547</id><published>2010-07-17T11:07:00.000-07:00</published><updated>2010-07-17T11:15:43.169-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-17T11:15:43.169-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Autovervollständigung" /><category scheme="http://www.blogger.com/atom/ns#" term="bash" /><title>bash Autovervollständigung die Zweite</title><content type="html">Gestern habe ich über die &lt;a href="http://blog.nils-andresen.de/2010/07/bash-autovervollstandigung.html"&gt;Autovervollständigung der bash geschrieben&lt;/a&gt;. Heute möchte ich kurz beschreiben wie ich das Verhalten verbessert habe.&lt;br /&gt;
Die noch fehlenden Funktionen waren:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Die Autovervollständigung von Verzeichnisnamen&lt;/li&gt;
&lt;li&gt;Die Autovervollständigung von csv-Dateien in anderen Verzeichnissen als dem aktuellen.&lt;/li&gt;
&lt;/ol&gt;Das Skript habe ich nun folgendermaßen abgeändert:&lt;br /&gt;
&lt;pre class="brush: bash; highlight: [6,25]"&gt;_csv2qif_possible_csvFiles()
{
   local curWord csvs optfiles
   curWord=${1}
   optfiles=""
   csvs=$( compgen -f -X "!*.csv" -- "${curWord}" )
   for file in ${csvs}; do
      if [ ! -f ${file/\.csv/.qif} ]; then
         optfiles="${optfiles} ${file}"
      fi
   done
   echo $optfiles
}

_csv2qif()
{
   local cur opts
   cur="${COMP_WORDS[COMP_CWORD]}"
   opts=$(_csv2qif_possible_csvFiles ${cur})

   COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
   return 0
}

complete -o plusdirs -F _csv2qif csv2qif.py
&lt;/pre&gt;&lt;br /&gt;
In Zeile 25 wird die Funktion Nr. 2 (&lt;i&gt;Autovervollständigung von Verzeichnisnamen&lt;/i&gt;) realisiert. Durch den Parameter &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-o&amp;nbsp;plusdirs&lt;/span&gt; wird die Liste der Autovervollständigung um die möglichen Verzeichnisse erweitert.&lt;br /&gt;
&lt;br /&gt;
In Zeile 6 wird die Funktion Nr. 1 (&lt;i&gt;andere Verzeichnisse als das aktuelle&lt;/i&gt;) realisiert. Die bash „hat da schon etwas vorbereitet“: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;compgen&amp;nbsp;-f&amp;nbsp;-X&amp;nbsp;"!*.csv"&amp;nbsp;--&amp;nbsp;"${curWord}"&lt;/span&gt; Stellt eine Liste für die Autovervollständigung zusammen. Und zwar werden hier für den Parameter &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;${curWord}&lt;/span&gt; alle passenden Dateien (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-f&lt;/span&gt;) mit der Endung .csv (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-X&amp;nbsp;"!*.csv"&lt;/span&gt;) Aufgelistet. Dabei wird schon bedacht, dass der Parameter auf ein anderes Verzeichnis zeigen könnte...&lt;br /&gt;
&lt;br /&gt;
Finde ich super.&lt;br /&gt;
Dieses Mal habe ich meine Inspiration in der &lt;a href="http://www.gnu.org/software/bash/manual/"&gt;bash-Referenz&lt;/a&gt; gefunden, unter &lt;a href="http://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.html#Programmable-Completion"&gt;Programmable-Completion&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-4168200276061236547?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/4168200276061236547/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2010/07/bash-autovervollstandigung-die-zweite.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/4168200276061236547?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/4168200276061236547?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2010/07/bash-autovervollstandigung-die-zweite.html" title="bash Autovervollständigung die Zweite" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C08DSHc8eyp7ImA9Wx5TFE0.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-8022036279715107230</id><published>2010-07-16T09:52:00.000-07:00</published><updated>2010-07-29T04:11:19.973-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-29T04:11:19.973-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Autovervollständigung" /><category scheme="http://www.blogger.com/atom/ns#" term="bash" /><title>bash Autovervollständigung</title><content type="html">Für ein bestimmtes Konto exportiere ich die Umsatzdaten aus dem Web-Frontend meiner Bank. Diese (merkwürdige) csv-Datei wandle ich dann in &lt;a href="http://en.wikipedia.org/wiki/QIF"&gt;qif&lt;/a&gt; um, da GnuCash kein csv importiert (den verwendeten Konverter findet man im &lt;a href="http://lists.gnucash.org/pipermail/gnucash-de/attachments/20100328/2af6f178/attachment.py"&gt;Archiv der GnuCash-De liste&lt;/a&gt;).&lt;br /&gt;
Da ich die cvs-Dateien und die qif-Dateien nebeneinander archiviere habe ich manchmal beim konvertieren das Problem, das ich nicht mehr so genau weiß, was es nun zu konvertieren gilt (bzw. welche csv-Dateien noch nicht konvertiert sind)....&lt;br /&gt;
&lt;br /&gt;
Abhilfe habe ich mir von der programmierbaren Eingabe-Vervollständigung der Bash versprochen. Meine Idee: Für die Eingabe-Vervollständigung sollten nur csv-Dateien in Betracht kommen und hier auch nur diese, für die noch keine Datei mit Endung qif besteht. Gedacht, getippt:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;_csv2qif_possible_csvFiles()
{
 local csvs optfiles
 optfiles=""
 csvs=$(find . -maxdepth 1 -iname "*.csv" | sed "s/\.\///g")
 for file in ${csvs}; do
  if [ ! -f ${file/\.csv/.qif} ]; then
   optfiles="${optfiles} ${file}"
  fi
 done
 echo $optfiles
}

_csv2qif()
{
 local cur opts
 cur="${COMP_WORDS[COMP_CWORD]}"
 opts=$(_csv2qif_possible_csvFiles)

 COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
 return 0
}

complete -F _csv2qif csv2qif.py
&lt;/pre&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;Diese Datei beim Starten der Bash mit einlesen oder bei &lt;a href="http://www.gentoo.org/"&gt;gentoo&lt;/a&gt; einfach in &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/etc/.bash_completion.d/&lt;/span&gt; oder &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;${HOME}/.bash_completion.d/&lt;/span&gt; kopieren und schon klappt's auch mit der Eingabe-Vervollständigung.&lt;br /&gt;
Geholfen hat mir übrigens die &lt;a href="http://www.debian-administration.org/article/An_introduction_to_bash_completion_part_1"&gt;Debian-Einführung zu bash completion&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;Screenshots finde ich bei Kommandozeilen-Tools immer nicht so toll, hier ist Trotzdem einer:&lt;a href="http://2.bp.blogspot.com/_iws8L1QpYns/TECNiez2ofI/AAAAAAAAAY0/sn3aorR1Seo/s1600/BashComp.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="443" src="http://2.bp.blogspot.com/_iws8L1QpYns/TECNiez2ofI/AAAAAAAAAY0/sn3aorR1Seo/s640/BashComp.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;Als mögliche Verbesserung bleibt noch die Suche der csv-Dateien nicht nur auf das aktuelle Verzeichnis zu beschränken, sondern einen eingegebenen pfad (z.B.: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;../csv/2010/Q3/&lt;/span&gt;) mit zu beachten, aber das hebe ich mir wohl mal für einen „Urlaub“ auf...&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Edit: Eine verbesserte Version findet sich in: &lt;a href="http://blog.nils-andresen.de/2010/07/bash-autovervollstandigung-die-zweite.html"&gt;bash Autovervollstandigung die Zweite&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-8022036279715107230?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/8022036279715107230/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2010/07/bash-autovervollstandigung.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/8022036279715107230?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/8022036279715107230?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2010/07/bash-autovervollstandigung.html" title="bash Autovervollständigung" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_iws8L1QpYns/TECNiez2ofI/AAAAAAAAAY0/sn3aorR1Seo/s72-c/BashComp.png" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CUcAQXs5cCp7ImA9WxFbFEk.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-1216636264803243385</id><published>2010-07-06T12:02:00.000-07:00</published><updated>2010-07-06T12:04:00.528-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-06T12:04:00.528-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="bash" /><category scheme="http://www.blogger.com/atom/ns#" term="backup" /><title>Webspace-Backup...</title><content type="html">Mir ist heute aufgefallen, dass die Sicherung meines webspace nicht so war wie ich es mir gewünscht hätte...&lt;br /&gt;
&lt;br /&gt;
Das Problem war das löschen der nicht mehr benötigten Dateien. (Dinge, die nicht mehr auf dem Server sind brauche ich auch nicht in der Sicherung...)&lt;br /&gt;
Bisher hatte ich "wget --mirror ..." auf einem cron-job, nur leider schaufelt wget immer nur Daten dazu, löscht aber keine alten Daten.&lt;br /&gt;
&amp;nbsp; &lt;br /&gt;
Nach etwas Suchen habe ich das Backup nun auf &lt;a href="http://lftp.yar.ru/"&gt;lftp&lt;/a&gt; umgestellt. Dazu habe ich auch gleich eine Mail-Benachrichtigung im Fehlerfall realisiert.&lt;br /&gt;
&lt;br /&gt;
Folgendes Skript läuft nun täglich:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;#!/bin/bash
pushd $(dirname $0) &amp;gt; /dev/null

lftp -c "set ftp:list-options -a;
open -u user,pass ftp://server.dom.de;
lcd backup-dir;
mirror \
       --use-cache \
       --delete \
       --allow-chown \
       --allow-suid \
       --no-umask \
       --parallel=2 \
       --exclude .listing \
       --exclude .configs \
       --exclude atd \
       --log=../mirror.log" \
 2&amp;gt; error.log \
 &amp;gt; /dev/null

if [ "$?" -ne 0 ]; then
   cat &amp;gt; last.mail.eml &amp;lt;&amp;lt;EOF
Subject: BACKUP nils-andresen.de FEHLGESCHLAGEN !!!
X-Priority: 1
Importance: High

 ---- ERROR-LOG: ----
EOF
   cat error.log &amp;gt;&amp;gt; last.mail.eml
   cat &amp;gt;&amp;gt; last.mail.eml &amp;lt;&amp;lt;EOF

 ---- MIROR-LOG: ----
EOF
   cat mirror.log &amp;gt;&amp;gt; last.mail.eml
   /usr/sbin/sendmail -i nils &amp;lt; last.mail.eml
fi

popd &amp;gt; /dev/null
&lt;/pre&gt;&lt;br /&gt;
Die Mail wird nur „intern“ (an den Benutzer nils) versendet, für mich ist das aber ausreichend...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-1216636264803243385?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/1216636264803243385/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2010/07/webspace-backup.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/1216636264803243385?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/1216636264803243385?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2010/07/webspace-backup.html" title="Webspace-Backup..." /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CkINQX4_cSp7ImA9WxFaE0Q.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-1962662249349442841</id><published>2010-06-24T03:41:00.000-07:00</published><updated>2010-07-17T11:16:30.049-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-17T11:16:30.049-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SQL" /><title>Auflistung aller Tabellen ohne PrimaryKey</title><content type="html">Für MS-Sql-Server:&lt;br /&gt;
&lt;pre class="brush: sql"&gt;select table_name 
from INFORMATION_SCHEMA.TABLES 
where 
 TABLE_NAME not in 
  (
   select distinct table_name 
   from INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
   where CONSTRAINT_TYPE = 'PRIMARY KEY '
  )
 and TABLE_TYPE = 'BASE TABLE'
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-1962662249349442841?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/1962662249349442841/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2010/06/tabellen-ohne-primarykey.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/1962662249349442841?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/1962662249349442841?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2010/06/tabellen-ohne-primarykey.html" title="Auflistung aller Tabellen ohne PrimaryKey" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;D04GQ3o8eyp7ImA9WxFRFkw.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-1669167483867746842</id><published>2010-04-30T01:24:00.000-07:00</published><updated>2010-04-30T01:25:22.473-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-30T01:25:22.473-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="word" /><title>Kommentare eines Word-Dokumentes als Liste erstellen</title><content type="html">Mein aktuelles Problem: In einem recht großen Word-Dokument möchte ich alle Kommentarte überarbeiten.&lt;br /&gt;
Die aufkommende Fragestellung: Kann ich alle Kommentare eines Word-Dokumentes als Liste erstellen?&lt;br /&gt;
&lt;br /&gt;
Eine kurze suche brachte mich zu &lt;a href="http://word.tips.net/Pages/T001046_Printing_Comments.html"&gt;http://word.tips.net/Pages/T001046_Printing_Comments.html&lt;/a&gt;. Das Ergebnis ist schon ganz brauchbar:&lt;br /&gt;
&lt;pre class="brush: vb"&gt;Sub KommentarlisteInNeuemDokument()
'
' KommentarlisteInNeuemDokument Makro
' Erstellt eine Liste aller Kommentare des aktuellen Dokumentes in ein neues Dokument.
'
    Dim oThisDoc As Document
    Dim oThatDoc As Document
    Dim c As Comment
    Dim sTemp As String
    Dim iPage As Integer

    Set oThisDoc = ActiveDocument
    Set oThatDoc = Documents.Add

    Application.ScreenUpdating = False
    For Each c In oThisDoc.Comments
        'Find page number of comment
        oThisDoc.Select
        c.Reference.Select
        iPage = Selection.Information(wdActiveEndAdjustedPageNumber)

        'Put info in new document
        oThatDoc.Select
        Selection.EndKey Unit:=wdStory
        sTemp = "Seite: " &amp;amp;amp; iPage
        Selection.TypeText Text:=sTemp
        Selection.TypeParagraph
        sTemp = "[" &amp;amp;amp; c.Initial &amp;amp;amp; c.Index &amp;amp;amp; "] " &amp;amp;amp; c.Range
        Selection.TypeText Text:=sTemp
        Selection.TypeParagraph
    Next
    Application.ScreenUpdating = True
End Sub
&lt;/pre&gt;&lt;br /&gt;
Vielleicht finde ich demnächst die Zeit das ganze etwas schöner zu gestalten.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-1669167483867746842?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/1669167483867746842/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2010/04/kommentare-eines-word-dokumentes-als.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/1669167483867746842?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/1669167483867746842?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2010/04/kommentare-eines-word-dokumentes-als.html" title="Kommentare eines Word-Dokumentes als Liste erstellen" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkMCSXs_eSp7ImA9WxFTEE8.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-2221373940813683015</id><published>2010-03-31T01:26:00.000-07:00</published><updated>2010-03-31T01:34:28.541-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-31T01:34:28.541-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="EntityFramework" /><title>Nachträglich OnDelete: Cascade im EF-Modell ?</title><content type="html">Ich hatte gerade auf einer bestehenden DB-Relation die "on update: Cascade" gesetzt, und daraufhin mein EF-Modell ge-updated.&lt;br /&gt;
Ein Blick in das edmx zeigte auch den erwarteten Eintrag im SSDL:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;Association Name="FK_Foo_Bar"&amp;gt;
  &amp;lt;End Role="Bar" Type="FooBarModel.Store.Bar" Multiplicity="1"&amp;gt;
 &amp;lt;OnDelete Action="Cascade" /&amp;gt;
  &amp;lt;/End&amp;gt;
  &amp;lt;End Role="Foo" Type="FooBarModel.Store.Foo" Multiplicity="*" /&amp;gt;
  &amp;lt;ReferentialConstraint&amp;gt;
 &amp;lt;Principal Role="Bar"&amp;gt;
   &amp;lt;PropertyRef Name="ID" /&amp;gt;
 &amp;lt;/Principal&amp;gt;
 &amp;lt;Dependent Role="Foo"&amp;gt;
   &amp;lt;PropertyRef Name="BarId" /&amp;gt;
 &amp;lt;/Dependent&amp;gt;
  &amp;lt;/ReferentialConstraint&amp;gt;
&amp;lt;/Association&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Leider stellte sich die Gewünschte Funktionalität nicht  ein: "A relationship is being added or deleted from an AssociationSet 'FK_foo_bar'. With cardinality constraints, a corresponding 'bar' must also be added or deleted."&lt;br /&gt;
Nach reichlich Ärger und ein wenig googeln war der Fehler schnell gefunden: das CSDL wird nicht automatisch mit angepasst.&lt;br /&gt;
&lt;br /&gt;
Nachdem also im CSDL-Teil der edmx folgendes manuell ergänzt wurde:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;Association Name="FK_Foo_Bar"&amp;gt;
  &amp;lt;End Role="Bar" Type="FooBarModel.Bar" Multiplicity="1"&amp;gt;
 &amp;lt;OnDelete Action="Cascade" /&amp;gt;
  &amp;lt;/End&amp;gt;
  &amp;lt;End Role="Foo" Type="FooBarModel.Foo" Multiplicity="*" /&amp;gt;
&amp;lt;/Association&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Funktioniert auch das Löschen mit onDelete:cscade &lt;br /&gt;
Bleibt nur zu hoffen, dass sich die update-Funktionen des Designers im EF4 deutlich verbessert...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-2221373940813683015?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/2221373940813683015/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2010/03/nachtraglich-ondelete-cascade-im-ef.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/2221373940813683015?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/2221373940813683015?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2010/03/nachtraglich-ondelete-cascade-im-ef.html" title="Nachträglich OnDelete: Cascade im EF-Modell ?" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DU4AQ3szfip7ImA9WxBaEkk.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-9054578182400728802</id><published>2010-03-22T01:52:00.000-07:00</published><updated>2010-03-22T01:52:22.586-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-22T01:52:22.586-07:00</app:edited><title>Geekfaktor…</title><content type="html">&lt;div&gt;Bei &lt;a href="http://thedatafarm.com/blog/"&gt;Julie Lerman&lt;/a&gt; habe ich &lt;a href="http://thedatafarm.com/blog/just-rambling/how-geeky-am-i/"&gt;gerade gelesen&lt;/a&gt;, dass man seinen Geekfaktor messen lassen kann – das musste ich natürlich ausprobieren:&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.oneplusyou.com/bb/geek" style="background: url(&amp;quot;http://www.oneplusyou.com/bb/css/img/quiz/geek_badge.jpg&amp;quot;) no-repeat scroll 0% 0% transparent; display: block; height: 82px; text-decoration: none; width: 268px;"&gt;&lt;span style="color: black; display: block; font-family: Arial; font-size: 22px; padding-left: 125px; padding-top: 28px;"&gt;68% Geek&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-9054578182400728802?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/9054578182400728802/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2010/03/geekfaktor.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/9054578182400728802?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/9054578182400728802?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2010/03/geekfaktor.html" title="Geekfaktor…" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;AkYARnkzeip7ImA9WxBbFEo.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-7550473901678144812</id><published>2010-03-11T01:45:00.000-08:00</published><updated>2010-03-13T03:02:27.782-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-13T03:02:27.782-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="neo-layout" /><title>Neo-Layout und Geschwindigkeit zum Zweiten.</title><content type="html">&lt;div&gt;Über das &lt;a href="http://www.neo-layout.org/"&gt;neo-Layout&lt;/a&gt; hatte ich ja &lt;a href="http://blog.nils-andresen.de/2009/09/neo-layout.html"&gt;bereits berichtet&lt;/a&gt;.&lt;br /&gt;
Ich bin mit meiner Geschwindigkeit immer noch nicht viel weiter...&lt;br /&gt;
&lt;a href="http://schnell-schreiben.de/stv2" style="-moz-background-inline-policy: continuous; background: url(&amp;quot;http://speedtest.schnell-schreiben.de/img/badge1.png&amp;quot;) no-repeat scroll 0% 0% transparent; color: #009933; display: block; font-family: Times New Roman,Arial,serif; font-size: 40px; font-weight: bold; height: 120px; padding-left: 60px; padding-top: 50px; text-decoration: none; width: 300px;"&gt;26 Wörter&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Aber dafür mit meiner Tastatur:&lt;br /&gt;
&lt;a href="http://3.bp.blogspot.com/_iws8L1QpYns/S5i5NMKYoVI/AAAAAAAAAX0/3Bo7ClB9WRw/s1600-h/NEO-keyboard.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="182" src="http://3.bp.blogspot.com/_iws8L1QpYns/S5i5NMKYoVI/AAAAAAAAAX0/3Bo7ClB9WRw/s400/NEO-keyboard.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div&gt;Problematisch ist an dem Ganzen, dass ich beim Arbeiten nicht "einfach" auf neo umstellen kann. (Man stelle sich einen Mitarbeiter vor, der nichts ahnend an meinen Rechner geht und etwas tippen will...)&lt;/div&gt;&lt;div&gt;Somit arbeite ich die meiste Zeit des Tages mit QWERTZ, bei längeren Texten schalte ich "heimlich" auf neo um (&lt;a href="http://wiki.neo-layout.org/wiki/Neo%20unter%20Windows%20einrichten/NeoVars"&gt;NeoVars&lt;/a&gt; sei Dank)...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-7550473901678144812?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/7550473901678144812/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2010/03/neo-layout-und-geschwindigkeit-zum.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/7550473901678144812?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/7550473901678144812?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2010/03/neo-layout-und-geschwindigkeit-zum.html" title="Neo-Layout und Geschwindigkeit zum Zweiten." /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_iws8L1QpYns/S5i5NMKYoVI/AAAAAAAAAX0/3Bo7ClB9WRw/s72-c/NEO-keyboard.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0UHQHYzfip7ImA9WxNUF0g.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-1772453285196335679</id><published>2009-11-09T01:31:00.000-08:00</published><updated>2009-11-09T01:33:51.886-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-09T01:33:51.886-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="wpf" /><category scheme="http://www.blogger.com/atom/ns#" term="winforms" /><category scheme="http://www.blogger.com/atom/ns#" term="nunit" /><title>NUnit im STA - Modus</title><content type="html">Neulich hatte ich die Anforderung, dass ein Programm Daten der Zwischenablage nutzen und modifizieren sollte. Ich habe (natürlich) angefangen einen Test zu schreiben. Leider war dies mit dem Unit-Test-Tool meiner Wahl (NUnit) nicht möglich. Der Fehler:&lt;br /&gt;
&lt;blockquote&gt;&lt;i&gt;System.Threading.ThreadStateException:&amp;nbsp;Der aktuelle Thread muss in den STA-Modus (Singlethreadapartment) gesetzt werden, bevor OLE-Aufrufe durchgeführt werden können.&lt;/i&gt;&lt;br /&gt;
&lt;/blockquote&gt;Der Fehler tritt im Übrigen auch auf, wenn man versucht UserControls zu testen und sollte für WPF und WinForms gleich sein.&lt;br /&gt;
Die Lösung des Problems: NUnit-Tests im&lt;a href="http://msdn2.microsoft.com/en-us/library/ms680112.aspx"&gt; Single-Threaded Apartment (STA)&lt;/a&gt; statt in der Vorgabe (&lt;a href="http://msdn2.microsoft.com/en-us/library/ms693421.aspx"&gt;Multithreaded Apartment (MTA)&lt;/a&gt;) laufen lassen. Das Vorgehen: Man erstellt eine einfache app.config mit folgendem Inhalt:&lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;configuration&amp;gt;
    &amp;lt;configSections&amp;gt;
        &amp;lt;sectionGroup name="NUnit"&amp;gt;
            &amp;lt;section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/&amp;gt;
        &amp;lt;/sectionGroup&amp;gt;
    &amp;lt;/configSections&amp;gt;
    &amp;lt;NUnit&amp;gt;
        &amp;lt;TestRunner&amp;gt;
            &amp;lt;!-- Valid values are STA,MTA. Others ignored. --&amp;gt;
            &amp;lt;add key="ApartmentState" value="STA" /&amp;gt;
            &amp;lt;!-- See ThreadPriority enum for other valid values --&amp;gt;
            &amp;lt;add key="ThreadPriority" value="Normal" /&amp;gt;
        &amp;lt;/TestRunner&amp;gt;
    &amp;lt;/NUnit&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/pre&gt;Damit läuft NUnit im STA, und die es kann auf die Zwischenablage zugegriffen werden.&lt;br /&gt;
Die Lösung habe ich von &lt;a href="http://weblogs.sqlteam.com/mladenp/archive/2007/03/22/60140.aspx"&gt;hier&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-1772453285196335679?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/1772453285196335679/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2009/11/nunit-im-sta-modus.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/1772453285196335679?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/1772453285196335679?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2009/11/nunit-im-sta-modus.html" title="NUnit im STA - Modus" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0YFR38_eip7ImA9WxNUE08.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-5982931812599332397</id><published>2009-11-03T23:51:00.000-08:00</published><updated>2009-11-03T23:51:56.142-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-03T23:51:56.142-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="EntityFramework" /><title>ReportPropertyChanged vs. OnPropertyChanged in Entities</title><content type="html">Gerade etwas länger mit folgender Fehlermeldung gerungen: &lt;i&gt;System.ArgumentException: Die Eigenschaft 'Foo' weist keine gültige Entitätszuordnung für das Entitätsobjekt auf. Weitere Informationen finden Sie in der Dokumentation zu Entity Framework.&lt;/i&gt;&lt;br /&gt;
Der Fehler trat immer auf,&amp;nbsp; wenn ich Foo einen wert zuweisen wollte.&lt;br /&gt;
&lt;br /&gt;
Ursache des Fehlers war, das ich meinem eigenen &lt;a href="http://blog.nils-andresen.de/2009/10/zusammengesetzte-properties-in.html"&gt;Post über Zusammengesetzte Properties&lt;/a&gt; nicht gefolgt war, sondern statt dessen auf diversen Settern noch &lt;i&gt;ReportPropertyChanged("Foo")&lt;/i&gt; programmiert hatte.&lt;br /&gt;
&lt;i&gt;ReportPropertyChanged&lt;/i&gt; ist abernicht das gleiche wie &lt;i&gt;OnPropertyChanged&lt;/i&gt;. &lt;i&gt;ReportPropertyChanged &lt;/i&gt;scheint noch mehr zu tun und funktioniert daher nur auf Properties aus Enities mit Entitätszuordnung.&lt;br /&gt;
Nachdem ich den Fehler gefunden hatte machte die Fehlermeldung auf einmal auch viel mehr sinn.&lt;br /&gt;
Die Lösung des Problems war also einfach nicht &lt;i&gt;ReportPropertyChanged&lt;/i&gt; zu benutzen, sondern &lt;i&gt;OnPropertyChanged&lt;/i&gt;.&lt;br /&gt;
(Und bei dieser gelegenheit noch einmal mein Vorgehen in diesem Fall zu überdenken, und mich etwas mehr an meine eigenen Posts halten.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-5982931812599332397?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/5982931812599332397/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2009/11/reportpropertychanged-vs.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/5982931812599332397?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/5982931812599332397?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2009/11/reportpropertychanged-vs.html" title="ReportPropertyChanged vs. OnPropertyChanged in Entities" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkMDRn06fCp7ImA9WxNVFEs.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-727618658006512687</id><published>2009-10-25T02:48:00.000-07:00</published><updated>2009-10-25T02:54:37.314-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T02:54:37.314-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="EntityFramework" /><title>BeforeSaveEvent in EntityFramework</title><content type="html">Neulich habe ich nach so etwas wie BeforeSave gesucht für meine Entities. Folgendes war meine Lösung (In einer partial class):&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;public partial class MyEntities
{
    partial void OnContextCreated()
    {
        this.SavingChanges += HandleSavingChanges;
    }

    private static void HandleSavingChanges(object sender, EventArgs e)
    {
        MyEntities context = (MyEntities) sender;
        //code....
    }
}
&lt;/pre&gt;In meiner partial-Klasse kann ich keinen Konstruktor erstellen. (Jedenfalls keinen, der schon an anderer Stelle definiert wurde...) Daher verwende ich &lt;i&gt;OnContextCreated&lt;/i&gt;. Dies ist eine Methode, die vom erzeugten Code ausgeführt wird. Hier hänge ich einfach einen Eventhandler an &lt;i&gt;SavingChanges.&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-727618658006512687?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/727618658006512687/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2009/10/beforesaveevent-in-entityframework.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/727618658006512687?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/727618658006512687?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2009/10/beforesaveevent-in-entityframework.html" title="BeforeSaveEvent in EntityFramework" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkEERHcyeSp7ImA9WxNVFEs.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-9039255619826726812</id><published>2009-10-02T08:30:00.000-07:00</published><updated>2009-10-25T02:56:45.991-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T02:56:45.991-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="EntityFramework" /><title>"Zusammengesetzte" Properties in EntityFramework</title><content type="html">Ich habe für EF-Objekte gerne mal "eigene" Properties in partial classes. Diese sind dann immer vonmindestens einer, gerne auch mehreren Properties der Entity abhängig.&lt;br /&gt;
Damit dann auch die richtigen PropertyChanged &amp;amp; -Changing Events erzeugt werden habe ich gerade folgendes gefunden: Alle Properties der EF-entities implementieren eine partial &lt;i&gt;OnFooChanging&lt;/i&gt; bzw. &lt;i&gt;OnFooChanged&lt;/i&gt; Methode, an die man sich in der partial class einfach "anhängen" kann. Etwa so:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public string MyTitle
{
   get
   {
      return this.Title;
   }
   set
   {
      this.Title = value;
   }
}

partial void OnTitleChanging(string unused)
{
   OnPropertyChanging("MyTitle");
}

partial void OnTitleChanged()
{
   OnPropertyChanged("MyTitle");
}
&lt;/pre&gt;BTW: "Navigierbare Properties" (damit meine ich Properties in EF-Objekten, die auf andere EF-Objekte verweisen) lösen &lt;b&gt;keinen&lt;/b&gt; PropertiyChanged Events aus. &lt;a href="http://blog.nicktown.info/2008/12/02/entity-framework-doesnt-support-inotifypropertychanged-on-some-properties.aspx"&gt;Hier&lt;/a&gt; findet sich ein kleiner Workaround dazu.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-9039255619826726812?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/9039255619826726812/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2009/10/zusammengesetzte-properties-in.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/9039255619826726812?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/9039255619826726812?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2009/10/zusammengesetzte-properties-in.html" title="&quot;Zusammengesetzte&quot; Properties in EntityFramework" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkEGQ3c-eCp7ImA9WxNVFEs.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-6483267823481239308</id><published>2009-09-30T08:56:00.000-07:00</published><updated>2009-10-25T02:57:02.950-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T02:57:02.950-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="wpf" /><title>ValidationErrors in xaml Controls</title><content type="html">Validation auf xaml-controls findet man "überall" im Netz.. z.B. kann man das so machen:&lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;Binding Path="Person" 
         Mode="TwoWay"&amp;gt;
 &amp;lt;Binding.ValidationRules&amp;gt;
  &amp;lt;ui:PersonValidationRule /&amp;gt;
 &amp;lt;/Binding.ValidationRules&amp;gt;
&amp;lt;/Binding&amp;gt;
&lt;/pre&gt;Nun habe ich aber keine möglichkeit auf einem Window sowas zu machen wie &lt;i&gt;Window.ChildsHaveErrors()&lt;/i&gt;. Aus dieser Lage hilft das Folgende:&lt;br /&gt;
&lt;pre class="brush: xml; highlight: [2, 6]"&gt;&amp;lt;Window [blah...]
  Validation.Error="ValidationError"&amp;gt;

&amp;lt;Binding Path="Person" 
         Mode="TwoWay"
   NotifyOnValidationError="True"&amp;gt;
    &amp;lt;Binding.ValidationRules&amp;gt;
        &amp;lt;ui:PersonValidationRule /&amp;gt;
    &amp;lt;/Binding.ValidationRules&amp;gt;
&amp;lt;/Binding&amp;gt;
&lt;/pre&gt;und im Code-Behind:&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;private int errorsInForm;
private void ValidationError(object sender, ValidationErrorEventArgs e)
{
   switch (e.Action)
   {
      case ValidationErrorEventAction.Added:
         this.errorsInForm++;
         break;
      case ValidationErrorEventAction.Removed:
         this.errorsInForm--;
         break;
   }
}
private bool WindowHasErrors
{
   get
   {
      return this.errorsInForm&amp;gt;0;
   }
}
&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;Auf der Window-Deklaration im xaml den &lt;i&gt;Validation.Error&lt;/i&gt;-Event setzten (&lt;i&gt;Validation.Error&lt;/i&gt; ist übrigens eine "attached dependency property", sollte also auf fast allen Elementen funktionieren...)&lt;/li&gt;
&lt;li&gt;Auf der Binding-Deklaration &lt;i&gt;NotifyOnValidationError&lt;/i&gt; auf &lt;i&gt;true&lt;/i&gt; setzen, damit wird der Fehler aus dem eigentlichen Element auf dem dieser entsteht hinaus "gebubbelt" (z.B. bis zum Window...)&lt;/li&gt;
&lt;li&gt;Im Code-Behind, im &lt;i&gt;ValidationError&lt;/i&gt;-EventHandler werden einfach die entstandenen Fehler gezählt (&lt;i&gt;ValidationErrorEventAction.Removed&lt;/i&gt; ist ein "ehemaliger Fehler"...)&lt;/li&gt;
&lt;li&gt;In &lt;i&gt;WindowHasError&lt;/i&gt; wird dann nur noch geprüft, ob die aktuelle Zahl der Fehler größer ist als 0.&lt;/li&gt;
&lt;/ul&gt;Meinungen dazu ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-6483267823481239308?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/6483267823481239308/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2009/09/validationerrors-in-xaml-controls.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/6483267823481239308?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/6483267823481239308?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2009/09/validationerrors-in-xaml-controls.html" title="ValidationErrors in xaml Controls" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkENR349cCp7ImA9WxNVFEs.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-6817050156049211790</id><published>2009-09-30T08:27:00.001-07:00</published><updated>2009-10-25T02:58:16.068-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T02:58:16.068-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="vs2008" /><title>VS2008 benötigt CLR-Typen von MS SQL 2008</title><content type="html">Ich habe leztens alles deinstalliert, das "*SQL*2008*" im Namen hatte, und meinen SQL-Server 2005 DeveloperED wieder installiert.&lt;br /&gt;
Ein paar Tage später musste ich feststellen, dass DB-Verbindungen mit meinem VS2008 nicht mehr möglich waren.Der Fehler war: "&lt;i&gt;Could not load file or assembly: Microsoft.SqlServer.Management.Sdk.Sfc in Visual Studio 2008 Server Explorer&lt;/i&gt;"&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lange Rede, kurzer Sinn: VS2008 benötigt für die DB-Verbindungen:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;i&gt;Microsoft SQL Server 2008 Management Objects (SMO)&lt;/i&gt; und&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Microsoft SQL Server System CLR Types&lt;/i&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;Beides gibts zum &lt;a href="http://www.microsoft.com/DOWNLOADS/details.aspx?familyid=B33D2C78-1059-4CE2-B80D-2343C099BCB4&amp;amp;displaylang=de"&gt;Download bei Microsoft&lt;/a&gt;.&lt;br /&gt;
Nachdem ich mir die Finger wund gesucht hatte um der Lösung auf die Schliche zu kommen habe ich auch &lt;a href="http://blog.alexonasp.net/post/Could-not-load-file-or-assembly-MicrosoftSqlServerManagementSdkSfc-in-Visual-Studio-2008-Server-Explorer.aspx"&gt;diesen Post&lt;/a&gt; gefunden, der das gleiche Problem beschreibt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-6817050156049211790?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/6817050156049211790/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2009/09/vs2008-benotigt-clr-typen-von-ms-sql.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/6817050156049211790?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/6817050156049211790?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2009/09/vs2008-benotigt-clr-typen-von-ms-sql.html" title="VS2008 benötigt CLR-Typen von MS SQL 2008" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0cFQnw-eyp7ImA9WxNUE04.&quot;"><id>tag:blogger.com,1999:blog-1878379071775960497.post-4538890973364724993</id><published>2009-09-30T08:27:00.000-07:00</published><updated>2009-11-04T02:36:53.253-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-04T02:36:53.253-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="unity" /><title>Verschiedene Implementationen des selben Interfaces mit Unity "injecten"</title><content type="html">PersonRepository und VorgangRepository sind zwei Implementationen eines Interfaces: IRepoistory&lt;br /&gt;
Um nun meinen DBAdapter, der (natürlich IDBAdapter implementiert und) beide IRepositories als parameter (natürlich in der richtigen Reihenfolge...) benötigt (Ob das eine tolle Idee war sei mal dahin gestellt.) instanziieren zu können, habe ich folgendes gemacht:&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;IUnityContainer container = UnityContainerProvider.UnityContainer;
container.RegisterType&amp;lt;IDbAdapter, DbAdapter&amp;gt;();
container.RegisterType&amp;lt;IRepository, PersonRepository&amp;gt;("Person");
container.RegisterType&amp;lt;IRepository, VorgangRepository&amp;gt;("Vorgang");
container.Configure&amp;lt;InjectedMembers&amp;gt;().ConfigureInjectionFor&amp;lt;DbAdapter&amp;gt;(
 new InjectionConstructor(
  new ResolvedParameter&amp;lt;IRepository&amp;gt;("Person"),
  new ResolvedParameter&amp;lt;IRepository&amp;gt;("Vorgang")
  ));
&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Configure&lt;injectedmembers&gt;()&lt;/injectedmembers&gt;&lt;/i&gt; - Ich will die Member der Injection steuern...&lt;/li&gt;
&lt;li&gt;&lt;i&gt;ConfigureInjectionFor&lt;dbadapter&gt;()&lt;/dbadapter&gt;&lt;/i&gt; - auf den DBAdapter instanzen&lt;/li&gt;
&lt;li&gt;&lt;i&gt;new InjectionConstructor()&lt;/i&gt; - der Konstruktor soll gesteuert werden&lt;/li&gt;
&lt;li&gt;&lt;i&gt;new ResolvedParameter&lt;irepository&gt;("Person")&lt;/irepository&gt;&lt;/i&gt; - IRepository soll mit dem Key "Person" aufgelöst werden.&lt;/li&gt;
&lt;/ul&gt;Etwas störend finde ich die Notwendigkeit dies über zwei Strings zu steuern, also wenn jemand eine bessere Idee hat.. Immer her damit.&lt;br /&gt;
&lt;br /&gt;
Edit: Etwas besser ist natürlich das IRepository noch zwei mal abzuleiten (wenn dies möglich ist...) einmal als&lt;br /&gt;
IPersonenRepository und einmal als IVorgangsRepository.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1878379071775960497-4538890973364724993?l=blog.nils-andresen.de' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.nils-andresen.de/feeds/4538890973364724993/comments/default" title="Kommentare zum Post" /><link rel="replies" type="text/html" href="http://blog.nils-andresen.de/2009/09/verschiedene-implementationen-des.html#comment-form" title="0 Kommentare" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/4538890973364724993?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1878379071775960497/posts/default/4538890973364724993?v=2" /><link rel="alternate" type="text/html" href="http://blog.nils-andresen.de/2009/09/verschiedene-implementationen-des.html" title="Verschiedene Implementationen des selben Interfaces mit Unity &quot;injecten&quot;" /><author><name>Nils</name><uri>http://www.blogger.com/profile/15100279964547170419</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry></feed>

