Posts mit dem Label .Net Code werden angezeigt. Alle Posts anzeigen
Posts mit dem Label .Net Code werden angezeigt. Alle Posts anzeigen

Wix Installer Custom Action Kompilieren mit msbuild x64

Versucht man mit msbuild 4 x64 eine Custom Action für den Wix Installer zu kompilieren, endet das meist in folgender Fehlermeldung:

 c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.targets(1360,9): warning MSB3245: Could not resolve
this reference. Could not locate the assembly "Microsoft.Deployment.WindowsInstaller, Version=3.0.0.0, Culture=neutral,
PublicKeyToken=ce35f76fcda82bad, processorArchitecture=MSIL". Check to make sure the assembly exists on disk. If this
reference is required by your code, you may get compilation errors. [C:\....CustomActi
ons\MyProjectCustomActions.csproj]
 
Dies liegt daran, dass das Auflösen des Assembly – Pfades nicht funktioniert.
Abhilfe schafft das Eintragen des folgenden Keys in die Registry:
image

HKLM\Software\Microsoft\.NetFramework\AssemblyFolders\Wix 3.7

Visual Studio–Direktfenster einblenden

Wer das Direktfenster im Visual Studio einblenden will ist sehr häufig am suchen.

Es gibt keinen Menüeintrag und die Tastatur – Shortcuts sind auch keine Hilfe.

Die einfachste Variante ist über das Befehlsfenster zu gehen.

Dazu einfach das Befehlsfenster öffnen und dann “immed” eingeben.

Fertig.

Technorati-Markierungen: ,,,,,

C++ CLI vs. C# Keywords

Hier ein paar Samples für die Umsetzung C# zu C++ / CLI

Statische Klassen

C#: public static class XYZ {}

C++ / CLI : public ref class XYZ abstract sealed {}

 

ReadOnly Member

C#: public readonly string Text = “Hallo Welt”;

C++ / CLI: public: initonly System::String^ Text = “Hallo Welt”;

 

Static Const

C#: public static const string NAME = “Wert”;

C++ / CLI: public: literal System::String^ NAME = “Wert”;

 

Namespace

C#: namespace DE.Firma.Produkt { … }

C++ / CLI: namespace DE { namespace Firma { namespace Produkt {…}}}

 

Technorati-Markierungen: ,,,,,,,

Visual Studio 2012 Update 2 (Servicepack 2) verfügbar

Den Download findet ihr hier: http://www.microsoft.com/de-de/download/details.aspx?id=38188

Es kommen zahlreiche neue Features hinzu wie zum Beispiel:

  • Verbesserungen beim Unittesting für Metro Apps
  • Erweitertes Unittesting für WindowsPhone
  • Sketchflow für Blend (Yeah :)
  • Erweitertes IntelliTrace

Außerdem noch endlos viele Bugfixes.

Details zu den Fixes und neuen Features findet ihr hier: http://support.microsoft.com/kb/2797912/en-us

 

SharePoint 2010 – Powertools für VisualStudio

Wer vorhandene Lösungen auf Sandboxed – Solutions umstellt kennt das Problem. Der Compiler “meckert” nicht wenn unerlaubte Funktionen, wie zum Beispiel SPRunWithElevatedPrivileges, aufgerufen werden.

Zwar zeigt die Visual Studio IntelliSense “unerlaubte” Objekte nicht an, wer jedoch Code wiederverwendet, muss mühsam von Hand durchschauen ob sicherheitsrelevante Aufrufe vorhanden sind.

Die Microsoft Visual Studio 2010 SharePoint Power Tools helfen unter anderem hier. Nicht erlaubte Aufrufe erzeugen dann einen Compilerfehler. So lassen sich einfach alte Codeteile auch in Sandboxed Solutions einbinden und prüfen.

Den Download findet ihr hier: http://visualstudiogallery.msdn.microsoft.com/en-us/8e602a8c-6714-4549-9e95-f3700344b0d9?SRC=VSIDE

Der Installer funktioniert übrigens auch auf einem x64 – System…

Kalenderwoche unter .Net ermitteln

Heute durfte ich für eine Auswertung die Kalenderwoche unter .Net ermitteln.
Nachdem ich das DateTime - Objekt intensiv angeschaut hatte, musste ich feststellen das es hier zwar Funktionen wie "GetDayOfYear" gibt allerdings keine über die sich die aktuelle Kalenderwoche ermitteln lässt.

Da eine Woche ja immer sieben Tage hat und man über die Funktion "GetDayOfWeeky" auch bequem den Wochentag erfährt ist die Berechnung der Kalenderwoche kein großes Problem.

Aber es geht auch anders.

Im Namespace System.Globalization versteckt sich ein Objekt mit dem Namen Calendar. Dieses hat eine Funktion "GetWeekOfYear" welches uns die Berechnung abnimmt.

Angewendet sieht es dann wie folgt aus:
1 System.Globalization.Calendar c = System.Globalization.CultureInfo.CurrentCulture.Calendar;
2 int week = c.GetWeekOfYear(DateTime.Now, System.Globalization.CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);

Sound's aus dem Lautsprecher unter .Net 2.0

Ich muss gerade eine "alte" Anwendung renovieren und diese dabei auch von Framework 1.1 auf Framework 2.0 updaten.

In nun eben dieser Anwendung bin ich auf die altbekannte Multimedia - API "WinMM.dll" mit der wichtigen Funktion
PlaySound(string pszSound, UIntPtr hmod, uint fdwSound);
gestoßen.

Ein Kollege meinte "die brauchen wir noch". Doch was viele gar nicht wissen, seit dem Framework 2.0 gibt es den kleinen aber feinen Namespace "System.Media".

Dieser erlaubt über die Klassen SoundPlayer und SystemSounds Wav - Dateien aus Streams und dem Filesystem, sowie eben SystemSounds abzuspielen.

Die vernünftigste Alternative zu WinMM.dll oder gar Console.Beep muss hier also lauten:
1 System.Media.SystemSounds.Beep.Play();


Viel Spaß beim Krachmachen.

MDI - Fensterliste unter .Net ohne Code

"Irgendwie" ging das...
Sogar "ohne Code" war mir in Erinnerung, aber ich habe die entsprechende Property nicht gefunden.

Dann ein Anhaltspunkt: ein ToolStripMenuItem hat eine ReadOnly Property "IsMdiWindowListEntry", aber leider keine Funktion um dies zu aktivieren.

Nach einigem Suchen fand ich die entsprechende Eigenschaft dann doch. Es ist eine Property des "MenueStrip" - Elements, also der Menüleiste.

Dort kann man über "MdiWindowListItem" ein "ToolStripMenuItem" (Menüeintrag) als Root für die Fensterliste definieren.

Und schon gibt's, "Out of the Box", die gewünschte Fensterliste ;-)

Drag & Drop im Treeview

Um in einer normalen "Winforms" - Anwendung Drag & Drop anzubieten müssen spezielle Events abgefangen und verarbeitet werden.

Gehen wir für ein Beispiel von einem Treeview aus in dem Elemente, z.B. Ordner, verschoben werden können.

Vorbereitung des Baumes:

  • Property "AllowDrop" auf true setzten

  • Eventhandler für "ItemDrag"

  • Eventhandler für "DragOver"

  • Eventhandler für "DragDrop"



Im Handler "ItemDrag" wird bestimmt welche Elemente gezogen werden können.
In unserem Beispiel sind das alle.
Das Ziehen wird dann wie folgt aktiviert:
1 private void tvwMainItemDrag(object sender, ItemDragEventArgs e)
2 {
3 DoDragDrop(e.Item, DragDropEffects.Move);
4 }


Nun erhalten wir beim Ziehen des Elements über unseren Treeview - Bereich permanent das Event "DragOver":

 1 private void tvwMainDragOver(object sender, DragEventArgse)
2 {
3 //Grundsätzliches Verweigern des Drop
4 e.Effect = DragDropEffects.None;
5
6 //Typ für den ein Drop erlaubt ist prüfen, alle anderen abweisen
7 if (!(e.Data.GetDataPresent(typeof(TreeNode)))) return;
8
9 //Es ist auch möglich Texte und Bilder etc. aus anderen Anwendungen zu akzeptieren
10 TreeNode sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
11
12 }


Optisch wird jetzt über den Move-Cursor signalisiert das die gezogene TreeNode hier abgelegt werden kann.

Beim "loslassen" wird dann das Event "DragDrop" gefeuert. Auch hier muss entsprechend reagiert werden:


 1 private void tvwMainDragDrop(object sender, DragEventArgse)
2 {
3 //Typ für den ein Drop erlaubt ist prüfen, alle anderen abweisen
4 if (!(e.Data.GetDataPresent(typeof(TreeNode)))) return;
5
6 TreeNode sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
7 //aus dem Baum herauslösen
8 sourceNode.Remove();
9
10 //Ziel feststellen
11 Point pt = tvwMain.PointToClient(new Point(e.X, e.Y));
12 TreeNode targetNode = (TreeNode)tvwMain.GetNodeAt(pt);
13
14 //Am Ziel einfügen
15 targetNode.Nodes.Add(sourceNode);
16
17 }


Dies ist nur ein einfaches Beispiel, welches durch diverse Logik erweitert werden muaa. Nötig ist zum Beispiel eine Prüfung ob die targetNode eine ChildNode der sourceNode ist (damit der Vater nicht zum Kind des Kindes wird und damit die Familie auslöscht).

Eine Prüfung sollte dafür schon im Event DragOver stattfinden und könnte so aussehen:
1 if (targetNode.FullPath.Contains(sourceNode.FullPath)) e.Effect = DragDropEffects.None;

ASP.Net URL's relativ zum Anwendungsverzeichnis

Hat man eine tolle ASP.Net - Anwendung geschrieben und möchte diese nun mit ein paar Grafiken verzieren, bietet es sich an dies über die (vorhandene ;) Masterpage zu erledigen.

Soweit so gut.

Hat man in seiner ASP.Net - Anwendung jedoch Ordner zum gruppieren der Inhalte und evtl. für das spätere setzen von Berechtigungen verwendet, gestaltet sich dies schon schwieriger.

Eine Grafik, in der Masterpage adressiert mit "img/bg.gif" wird auf einer ASP.Net Seite zum Beispiel "User.aspx" in einem Ordner "Admin" referenziert als "Admin/img/bg.gif".

Dort ist diese Grafik jedoch leider nicht zu finden. Eine relative URL - Angabe mit "../img" funktioniert auch nicht, da dann Seiten die oberhalb des Admin - Ordners liegen die Grafik nicht finden können. Eine Referenzierung über "/img/" bedeutet jedoch das das Verzeichnis mit den Grafiken möglicherweise außerhalb des Anwendungverzeichnisses liegt.

Die Lösung in diesem Dilemma ist die Referenzierung per "~/img". "~/" Referenziert beim ASP.Net immer das Root-Verzeichnis der Webanwendung. Genau das was wir brauchen.

Leider können die Browser mit dieser Angabe nichts anfangen, da diese nicht wissen welches Verzeichnis das Root der Webanwendung ist.

Hier gibt es einen sinnvollen Einsatz von Inline Code:

<body style="background-image: url(<% Response.Write(Page.ResolveUrl("~/img/bg.gif")); %>); background-repeat: no-repeat;" >




So adressierte Grafiken (und anderer Dateien) werden vom Server in einen Absoluten Pfad aufgelöst und können vom Browser problemlos geladen werden.

ASP.Net DateTime - Picker

Häufig muss man in WebFormularen Datum und Uhrzeit oder nur ein Datum abfragen.
Leider gibt es dazu nichts brauchbares im Funktionsumfang des .Net Framework.

Also gibt es zwei Möglichkeiten:
  1. Selbermachen
  2. Auf ein vorhandenes Control zurückgreifen
Ein für mich passende Lösung habe ich hier gefunden: http://www.i386.com/...

Schlicht, funktional und gut konfigurierbar.

Die Bibliothek und Beispiele gibt es sogar Kostenlos zum Download:

Download for .NET 2.0
Download for .NET 1.1

Eigene Controls für Webparteigenschaften

Manchmal erstellt man einen WebPart, der eine spezielle Konfiguration zur Bewältigung seiner Aufgabe benötigt.
Beispielsweise soll er Daten einer Liste in aufbereiteter Form anzeigen.

Nun wäre es schön, wenn die Auswahl der Liste nicht über eine Textbox, in welche man ihren Namen einträgt, erfolgt, sondern über eine Combobox die alle passenden Listen zur Auswahl anbietet.

Hierfür wird ein sogenannter Toolpart verwendet. Ein Toolpart erbt von der Klasse "Microsoft.SharePoint.WebPartPages.ToolPart" und stellt einen selbst definierten Eingabebereich in der Toolbox des Webparts zur Verfügung.

Beispiel für den Aufbau eines Toolparts:
 1 internal class TPWebTemplates:Microsoft.SharePoint.WebPartPages.ToolPart
2 {
3 //wird später zum Auslesen des Wertes verwendet
4 private string inputIDListName;
5
6 public TPWebTemplates()
7 {
8 this.Title = "Template";
9 this.Init += new EventHandler(InitObject);
10 }
11 private void InitObject(object sender, System.EventArgs e)
12 {
13 //eindeutige ID für das Asuwerten des Steuerelementes
14 inputIDListName = this.UniqueID + "messageList";
15 }
16
17 /// <summary>
18 /// Auslesen der Änderungen
19 /// </summary>
20 public override void ApplyChanges()
21 {
22 WPSample wp1 = (WPSample)
23 this.ParentToolPane.SelectedWebPart;
24
25 value = Page.Request.Form[inputIDListName];
26 if (!String.IsNullOrEmpty(value)) wp1.ListName = value;
27 }
28
29
30 protected override void RenderToolPart(System.Web.UI.HtmlTextWriter output)
31 {
32 output.Write("Template: ");
33 System.Web.UI.WebControls.DropDownList cboToolpart = new System.Web.UI.WebControls.DropDownList();
34
35 foreach (Microsoft.SharePoint.SPList list in Microsoft.SharePoint.SPContext.Current.Web.Lists)
36 {
37 if (list.Hidden == false) //Nur Listen anzeigen, die nicht versteckt sind
38 {
39 System.Web.UI.WebControls.ListItem li = new System.Web.UI.WebControls.ListItem();
40 li.Text = list.Title;
41 li.Value = list.Title;
42 cboToolpart.Items.Add(li);
43 }
44 }
45 //Hier kann Code zum Anzeigen eines bereits gewählten Wertes folgen
46 }
47 }



Dieser Toolpart referenziert jetzt den WebPart WPSample mit der Property ListName. Besser wäre es hier ein enstprechendes Interface zu vereinbaren.

Der WebPart selbst wird ganz "normal" erstellt.
Einziger Unterschied ist die Überladung der Methode "GetToolParts" durch welche wir den Sharepoint über den zusätzlich darzustellenden Toolpart informieren.

Beispiel:
1 public override Microsoft.SharePoint.WebPartPages.ToolPart[] GetToolParts()
2 {
3 List<Microsoft.SharePoint.WebPartPages.ToolPart> parts = new List<Microsoft.SharePoint.WebPartPages.ToolPart>();
4 parts.Add(new Microsoft.SharePoint.WebPartPages.WebPartToolPart());
5 parts.Add(new Microsoft.SharePoint.WebPartPages.CustomPropertyToolPart());
6 parts.Add(new TPWebTemplates());
7 return parts.ToArray();
8 }


Im Ergebniss sieht das dann in etwa so aus:



Denkbar sind auch komplexere Eingaben z.B. für das Erstellen von Datenbankverbindungen oder Abfragen von WebServices.

Nur eine Instanz einer .Net Anwendung

Diese Klasse hilft einen Anwendung nur einmal zu starten.

Der Code prüft ob bereits einen Instanz der Anwendung läuft und bringt diese dann auf Wunsch in den Vordergrund. Die neu gestartete Instanz kann dann über Application.Exit() beendet werden.

Hinweis: Fenster die minimiert oder unsichtbar sind werden nicht in den Fordergrund gebracht. Hier ist die Implementierung der APIAufrufe "GetWindowPlacement" und "SetWindowPlacement" erforderlich.



 1 using System;
2 using System.Windows.Forms;
3 using System.Runtime.InteropServices;
4
5
6 namespace Toolbox
7 {
8 /// <summary>
9 /// This class helps to create a Application which allowed onyl on instance (like word, excel, eg)
10 /// </summary>
11 internal abstract class SingleInstanceManager
12 {
13 //TODO: create your own GUID with GuidGen!!!
14 private const string APPID="{AD0C0725-18BE-4eaa-8FE6-17F0FC14A971}";
15
16 #region Win32API
17 [DllImport("user32.dll")]
18 private static extern long BringWindowToTop(long hwnd);
19
20 [DllImport("user32.dll")]
21 private static extern long SetForegroundWindow(long hwnd);
22 #endregion
23
24 #region Worker
25
26 /// <summary>
27 /// check whether an other instance of the current application is running
28 /// </summary>
29 /// <returns>
30 /// true if you can start a new instance,
31 /// false if an instance is running
32 /// </returns>
33 public static bool StartNewApplication()
34 {
35 return StartNewApplication(false);
36 }
37
38 /// <summary>
39 /// check whether an other instance of the current application is running
40 /// </summary>
41 /// <param name="BringToTop">
42 /// true: the other instance will shown
43 /// false: the other instance will not shown
44 /// </param>
45 /// <returns>
46 /// true if you can start a new instance,
47 /// false if an instance is running
48 /// </returns>
49 public static bool StartNewApplication(bool BringToTop)
50 {
51 bool retVal = true;
52 System.Threading.Mutex mu = new System.Threading.Mutex(false, APPID);
53
54 if (mu.WaitOne(0, false) == true)
55 {
56 //start a new one
57 retVal = true;
58 }
59 else
60 {
61 //an instance is running
62 retVal = false;
63
64 if (BringToTop)
65 {
66 foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName))
67 {
68 if (p.Id != System.Diagnostics.Process.GetCurrentProcess().Id)
69 {
70 //p.MainWindowHandle;
71 SetForegroundWindow(p.MainWindowHandle.ToInt64());
72 BringWindowToTop(p.MainWindowHandle.ToInt64());
73 }
74 }
75 }//end BringToTop
76
77 }//end Running ?
78 return retVal;
79 }
80 #endregion
81 }
82 }
83

Screenshoots mit C#

Mit Hilfe des unten verlinkten Code-Snipplets können Screenshots aus eigenen Anwendungen heraus erstellt werden.

Dabei bestehen folgende Möglichkeiten:

  • vollständiger Desktop

  • aktives Fenster

  • benutzerdefinierter Bereich

  • anhand des Handels des Fensters



http://dotnet-snippets.de/dns/Snippet_detail.aspx?=434