ok ich probiers mal mit gacutil.exe
haut prinzipiell hin, muss dann nur den aufruf von
cgacutil /i \Storage Card\xxx\log4net.dll in das image bekommen
ja zur laufzeit - an GAC hatte ich auch schon gedacht - aber wir (nur kopieren, registrieren) ?
nur arbeite ich mittels .net cf und das betriebssystem wird anfangs aus einem image geladen - ich möchte daher log4net.dll nicht unbedingt ins das image reingeben; möchte später diese dll einfacher austauschen können, ohne ein neues image zu generieren
habe vergessen zu erwähnen, dass die entwicklungsumgebung auf einer anderen maschine ist, und somit dort der ordner für log4net ganz anderswo liegt
ich glaube es würde mittels Assembly.LoadFrom funktionieren, leider habe ich den logger static in der klasse und somit kommt das Assembly.LoadFrom zu spät
ich möchte einfach nur 1 version der dll (und auch nur 1 file) auf der zielmaschine warten müssen und nicht eben für jede app die log4net verwendet
vielleicht in den system ordner kopieren ?
habe 2 getrennte consolen apps (CA1.exe, CA2.exe).
beide verwenden zur zeit log4net => es gibt jeweils diesselbe log4net.dll im app-folder
möchte aber folgendes erreichen:
c:\Log4Net\log4net.dll
c:\Log4Net\log4net.config.xml
c:\App1\CA1.exe
c:\App2\CA2.exe
(CA1.exe und CA2.exe müssen in getrennten verzeichnissen sein)
dh die log4net.dll sollte nur einmal auf der maschine vorkommen
ok das war auch meine überlegung damit wcf und client nicht starr sind ...
habs probiert aber haut so nicht hin:
im wcf project habe ich FileItem1 entfernt
heu lib mittels FileItem1 erstellt, die DataContract/DataMember attribute auf conditional gesetzt (#if ...)
nur muss ich ja nun in der lib immer die conditional compile umsetzen, das geht dann aber nicht, denn ich brauche für DataContract/DataMember auc hdie zugehörigen referenzen (servicemodel, runtime.serialization) und die sieht zwischen .net 3.5 und .net cf 3.5 unterschiedlich
toll wäre es, wenn ich die directive im wcf setzen könnte, die mir dann die lib dementsprechen kompiliert....
dachte ich mir auch bereits aber consoleApp läuft unter .net cf 3.5 und hier habe ich kein DataContract/DataMember attribute - die könnte ich aber mittels compiler directiven wegschalten;
gibt es für die target framework version bereits vordefinierte directiven ?
zb
#if CF35
#else
#endif
habe ein wcf service application project. das service bietet eine funktion 'GetFileListFromServer' an und retourniert eine liste von FileItem1's (ein FileItem1 besteht aus id,filename,fileattribute)
getrennt davon gibt es ein consolen project, welches einen generierten client für das wcf-service verwendet (mittels svcutil)
zusätzlich kann das consolenprogramm aber auch eine funktion 'GetFileListFromDrive' aufrufen, welche auch eine liste von Items liefert (item besteht auch aus id,filename,fileattribute)
dh. consoleApp.exe ruft einerseits 'GetFileListFromServer' (service) und andererseits 'GetFileListFromDrive' (lokal) auf
zusätzlich soll die consoleApp die erhaltenen daten auch in einer liste halten.
mein erster ansatz dafür ist eine liste aus objekten einer klasse FileItem2, die mit den erhaltenen daten gefüllt wird (entweder vom service mit FileItem1's oder lokal mit Item's)
nun ist die klasse FileItem2 sehr ähnlich FileItem1 aus dem wcf service project; daher dachte ich nach, FileItem1 aus der generierten proxy klasse zu verwenden :
==> da hätte ich aber eine sehr starre verknüpfung von meiner consoleApp zum wcf service project.
auch würde bei wegfallen des services (und damit auch der proxy klasse) die klasse FileItem1 nicht mehr existieren und ich müsste mir für den aufruf von 'GetFileListFromDrive' eh wieder eine neue klasse (FileItem2) basteln
jedoch gefällt mir der umstand nicht so sehr, dass FileItem1 und FileItem2 fast ident (und somit unnötig doppelt vorhanden) sind
hoffentlich habe ich mich etwas verständlich ausgedrückt und jemand kann dazu stellung nehmen - danke
ist nun so gelöst :
Array.Sort(pInfoArr, new CustomPropertyComparer());
class CustomPropertyComparer : IComparer<PropertyInfo> {
#region IComparer<PropertyInfo> Members
public int Compare(PropertyInfo x, PropertyInfo y) {
return (Attribute.GetCustomAttribute(x, typeof(XmlElementAttribute)) as XmlElementAttribute).Order.CompareTo
((Attribute.GetCustomAttribute(y, typeof(XmlElementAttribute)) as XmlElementAttribute).Order);
}
#endregion
}
ja das mit dem IComparer habe ich schon in der engeren auswahl -
wollte nur was kürzeres ...
Array.Sort(pInfoArr,
delegate(PropertyInfo pInfo1, PropertyInfo pInfo2) {
return (Attribute.GetCustomAttribute(pInfo1, typeof(XmlElementAttribute)) as XmlElementAttribute).Order.CompareTo
((Attribute.GetCustomAttribute(pInfo2, typeof(XmlElementAttribute)) as XmlElementAttribute).Order);
});
habe folgende klasse:
public class MyClass {
string _text;
string _num;
[XmlElement(ElementName = "Num", IsNullable = true, Order = 2)]
public string Num {
get { return _num; }
set { _num= value; }
}
[XmlElement(ElementName = "Text", IsNullable = true, Order = 1)]
public string Text {
get { return _text; }
set { _text= value; }
}
}
hole mir wie folgt ein PropertyInfo array von MyClass
PropertyInfo[] pInfoArr = typeof(MyClass).GetProperties();
wie kann ich pInfoArr nun sortieren über XmlElement -> Order (habe nur .net 2.0 ohne linq ecc) ?
danke
habe ein cab-file (enthält applikation für windows ce)
möchte dieses signieren (mit visual studio, signtool ?) und anschliessend auf dem windows ce device eine signatur-prüfung in c# durchführen (compact framework 2)
mit welchen mitteln kann ich dies erreichen ?
danke
ist es möglich, aus einer SerialPort-instanz den handle des ports zu bekommen (IntPtr) - für pinvoke aufrufe (ReadFile/WriteFile)
hab mir folgendes durchgelesen (recht interessant):
Query Performance Tuning (SQL Server Compact)
da ich im order by nun datetime UND id drinnen habe, ist der index auch auf die spalte id erweitert worden - das UNIQUE habe ich weggelassen, da id eh schon primary key ist 😉
habe nun mein select erweitert:
select txt from tbl where x<datetime and datetime<y order by datetime , id
und index dann wie folgt:
CREATE INDEX IX_TestIndex_DateTime_Id
ON TestIndex (DateTime, Id);
das unique habe ich weggelassen, da id eh schon eine identity ist
hi danke für die antwort - IGNORE_DUP_KEY ist mir nun klar
die spaltennamen sind eh nicht datetime 😉 sondern nur der typ
bringt mir die Id wirklich was im index ? :
In the context of multiple-column indexes, for ORDER-BY or GROUP-BY to consider a particular index, the ORDER-BY or GROUP-BY columns must match the prefix set of index columns with the exact order. For example, the index CREATE INDEX Emp_Name ON Employees ("Last Name" ASC, "First Name" ASC) can help optimize the following queries:
... ORDER BY / GROUP BY "Last Name" ...
... ORDER BY / GROUP BY "Last Name", "First Name" ...
It will not help optimize:
... ORDER BY / GROUP BY "First Name" ...
... ORDER BY / GROUP BY "First Name", "Last Name" ...
meine abfrage hat im where nur die datetime spalte und im order by nur die id
dh. ein index:
CREATE UNIQUE INDEX IX_TestIndex_DateTime_Id
ON TestIndex (DateTime, Id);
würde mir dann laut msdn nicht für
select txt from tbl where x<datetime and datetime<y order by id
helfen ... sondern nur fall ich auch datetime in das group by mitaufnehmen würde - oder ?
verwendetes Datenbanksystem: compact sql 35
habe eine tabelle bestehend aus 3 spalten (id, datetime, text)
eine abfrage selectiert über eine zeitraum (select txt from tbl where x<datetime and datetime<y order by id)
id ist primary key, datetime ist nicht unique
ab wievielen einträgen kann es mit der abfrage zu performanceproblemen kommen ?
wie könnte ich am besten einen index setzen ? (datetime ist nicht unique und IGNORE_DUP_KEY gibt es ja meines wissens beim compact sql server nicht)
danke
verwendetes Datenbanksystem: sql ce 35
versuche in einem SqlCeCommand ein create table + create index zu machen - leider klappt dies nicht (parse error ...):
using (conn = new SqlCeConnection(ConnStr)) {
conn.Open();
SqlCeCommand cmd = conn.CreateCommand();
cmd.CommandText =
"CREATE TABLE [TEST] (" +
"[ID] bigint NOT NULL IDENTITY (1,1), " +
"[MYC] smallint NOT NULL); " +
"CREATE UNIQUE INDEX idxERFDTE ON TEST (MYC);";
cmd.ExecuteNonQuery();
}
wenn ich create table + create index einzeln aufrufe, dann funktioniert es ohen probleme
eigentlich meinte ich nur, ob diese deserialisierung vom prinzip her ok ist oder ob es zu problemen kommen kann, wenn es member gibt, die klassen sind
habe nun versucht mittels reflection zu deserialisieren
meine TestClass hat unter anderem auch klassen als member - wie werden die werte dafür gesetzt : deep/shallow ?
class MyClass {
int _num;
public int Num {
get { return _num; }
set { _num = value; }
}
}
class TestClass {
string _s;
public string S {
get { return _s; }
set { _s = value; }
}
MyClass _myClass = new MyClass();
public bool Deserialize(MemoryStream ms) {
bool bRetVal = false;
try {
TestClass tmp = serial.Deserialize(ms) as TestClass;
foreach (PropertyInfo pi in tmp.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
this.GetType().GetProperty(pi.Name).SetValue(this, pi.GetValue(tmp, null), null);
}
bRetVal = true;
} catch (Exception) {
}
return bRetVal;
}
}
hab mal meine testklasse eingefügt (länge der strings ist fix):
class PInvokeTest {
[DllImport("Test.dll")]
public static extern void Test(byte[] buf);
public static void Main() {
byte[] buf = new byte[5];
Test(buf);
string s = Encoding.ASCII.GetString(buf);
}
}
dh ich müsste den marshalling typ von byte[] buf auf String stellen ?
GETDATE() habe ich in verwendung
dachte, da CURRENT_TIMESTAMP ein reserviertes wort in cf ist, dass dies auch funktionieren würde
verwende eine c-dll welche mir ein byte buffer in .net zur verfügung stellt
nun kann es vorkommen, dass dieser buffer in der dll mittels memset über die ganze länge auf 0x00 gesetzt wird
bekomme ich nun diesen buffer in .net und bilde daraus wie folgt einen string
string s = Encoding.ASCII.GetString(buf);
dann enthält s natürlich den wert '\0\0\0...'
gibt es eine vorhandene methode, um im obigen fall einen string.empty zu bekommen (ohne jetzt explizit den buffer auf '\0' zu durchsuchen) ?
sql server compact 3.5
wie kann ich in einer sql server compact 3.5 db ein CURRENT_TIMESTAMP via insert einfügen (spalte datetime existiert)
CURRENT_TIMESTAMP scheint zwar reserviert zu sein, kanns aber nicht inserten (error parse token ...)
GETDATE() scheint zu funktionieren ...
das problem ist, das mir Dispose nicht angezeigt wird (ist protected ,CF2) ...
habe ein klasse, welche IDisposable implementiert
in dieser möchte ich auch einen streamwriter verwenden, um zeilenweise auf ein file zu schreiben
mittels Open wird ein neuer StreamWriter erzeugt
wie kann ich diesen StreamWriter richtig disposen (mittels eigener klasse und ableiten von StreamWriter) ?
class Test : IDisposable {
StreamWriter _wr;
public string FName { set; }
private bool _disposed;
~FilePrinter() {
Dispose(false);
}
private void Dispose(bool disposing) {
if (_disposed)
return;
if (disposing) {
//DISPOSE STREAMWRITER ???
}
_disposed = true;
}
public void Open() {
_wr = new StreamWriter(File.Open(FName, FileMode.Append, FileAccess.Write));
}
public void Close() {
_wr.Close();
}
public void Write(string s) {
_wr.WriteLine(s);
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
}
möchte folgenden string replace mittels regex realisieren (inputstring besteht nur aus nummern und hat fixe länge - outputstring hat länge (inputstring + 1)):
VORHER -> NACHHER
"1234567" -> "1234-567"
"0012345" -> " 12-345"
"0000000" -> " 0-000"
string data = "1234-567";
data = Regex.Replace(data, @"^(0*)(\d+)(\d{3})$", "$2-$3").PadLeft(data.Length + 1);
ist es möglich, das PadLeft irgendwie direkt auf die backreference $1 zu machen ?
versuche eine datetime spalte zu befüllen (c#, tableadapter generiert von vs)
dh insert eines c#-datetime wertes in eine sqldb-column [typ datetime] .
ja ist erledigt danke
btw : hatte im startbeitrag das jahr 1111, zulässig ist aber erst ab 1753 - deshalb der overflow in der db
bei einem insert über tableadapter ...
habe die unter grenze von minvalue unterschritten (siehe meine vorherige antwort)
The minimum valid date for a SqlDateTime structure is January 1, 1753.
The maximum valid date for a SqlDateTime structure is December 31, 9999.
dh dann evtl nur ein tableadapter und ein lock ...
die daten müssen auch nach einem neustart vorhanden sein 😉
eine db schafft ja mehrere connections gleichzeitig, daher meine frage, ob zwei threads mit zwei tableadapterinstanzen passend wären ...
ja aber es geht nun um eine db-spezifische frage ...
wird eine datetime grenze im sql server sein (habe mit 11/11/1111 versucht, dann error) ...
verwendetes Datenbanksystem: <sql server compact 3.5>
versuche eine datetime spalte zu befüllen (c#, tableadapter generiert von vs)
mittels DateTime
DateTime dt = new DateTime(1901, 1, 1);
funktioniert es
aber mit
DateTime dt = new DateTime(1901, 1, 1, 11, 11, 11);
gibt es den error 'An overflow occurred while converting to datetime'
ein thread empfängt daten, die geloggt werden müssen
der userthread kann diese daten dann jederzeit ausdrucken
verwendetes Datenbanksystem: sql compact 3.5
habe 2 threads
beide sollen unabhängig voneinander die datenbank benutzen können (einer nur lesend, einer nur schreibend)
wie wird das am besten erledigt (1 getrennter tableadapter pro thread) ?
danke
würde es so machen:
class Test {
Object _lockObj = new Object();
int _prop;
Unmanaged _un;
Test() {
_un.DataEcvEv += new CallbackDel(DataReceived);
}
void DataReceived() {
lock(_lockObj) {
if (_prop!= 0) _prop++;
}
}
void DoSomething() {
lock(_lockObj) {
if (_prop> 10) _prop--;
}
}
}
hi JAck30lena
das mit atomar ist mir klar - das int property sollte nur ein beispiel sein, an diese stelle kommt wahrscheinlich ein struct oä
nur wieso sollte das lockobjekt public sein ?
auf das property (nicht public) greifen ja nur die klasse Test und der handler DataReceived zu:
class Test {
Object _lockObj = new Object();
int _prop;
int Prop {
get { lock (_lockObj) { return _prop; } }
set { lock (_lockObj) { _prop = value; } }
}
Unmanaged _un;
Test() {
_un.DataEcvEv += new CallbackDel(DataReceived);
}
void DataReceived() {
if (Prop != 0) Prop++;
}
void DoSomething() {
if (Prop > 10) Prop--;
}
}
das property könnte ich mir auch sparen und das lock direckt auf die membervariable _prop anwenden ...
das problem ist, dass es ein file geben muss, da auch nach pc-neustart die daten vorhanden sein müssen
habe jetzt um die fileoperatoren das locking wieder eingeführt
zu meinem code noch eine kleine frage :
möchte zusätzlich ein property verwenden, welches von Test und DataReceived verwendet wird => hier wird ein lock nötig sein, und der zugriff löuft dann nur mehr über das (gelockte) property ?
class Test {
Object _lockObj = new Object();
int _prop;
int Prop {
get { lock (_lockObj) { return _prop; } }
set { lock (_lockObj) { _prop = value; } }
}
Unmanaged _un;
Test() {
_un.DataEcvEv += new CallbackDel(DataReceived);
}
void DataReceived() {
// if specific response then enque in queue
Prop = 4;
}
void SendAndWaitForResp() {
//send request
//wait for a specific response
// check queue
//zb
Console.WriteLine(Prop.ToString());
}
}
es wird nicht über files kommuniziert sondern ein thread schreibt daten in das file (ähnlich logdaten) und ein thread kann diese daten wieder ausgeben
das mit lock hatte ich eh - nur dachte ich wenn einer NUR liest und einer NUR schreibt wäre gleichzeitig möglich
... multithreading und synchronisation ist mir schon klar 😉
getestet mit File.OpenRead / File.AppendText
The process cannot access the file 'c:\test.txt' because it is being used by another process.
ist gleichzeitiges lesen (thread 1) und schreiben (thread2) einer textdatei threadsafe ?
thread 1 liest nur
thread 2 schreibt nur
danke habe ich mittlerweile auch mittels Resources-Designer eingefügt
ja danke der hinweis ist mir bekannt - aber habe nur 1 producer und 1 consumer in diesem projekt ...