Jag har major problem! När man skickar strängar mellan funktioner så skickar man aldrig själva strängen, utan man skickar ett tal som talar om var i minnet strängen finns. Talet är 32 bitar stort, dvs lika stort som ett DWORD, så det är väl därav det kommer. Om du bara ska anropa funktionen med WTSUserConfigTimeoutSettingsConnections kan du ändra deklarationen till tack för tipsen, men inget verkar funka... >jag ändrade till pBuffer as any och skickade in byVal x , men då fick jag minnes fel. Något annat tips, jag blir tokig snart... Hej pBuffer är väl värdet på det som ska sättas? det är det iaf på alla andra WTS propertys.. > men då fick jag minnes fel. Hej Hej igen Nu hänger jag inte riktigt med... Igen Igen vadå Label1.Caption = WTS.TimeOut??? Hej igen b är true eller false beroende på om det gick att sätta timeouten. men timeouten blir helt skum, typ 6dagar, eller 52 minuter, inget stämmer... Hej det blir ingen skillnad, VB tar dessutom bort &-tecknet. det kan väl inte vara såhär svårt att använda detta api, alla andra properties går hur bra som helst att sätta... Hej igen Hur ser den anropande koden ut då? Jag såg att du använde Variant nedanför, vilket skulle kunna ställa till problem. Funkar inte detta? Hej MS Hej > Det köper jag inte , det står tydligt att den skall vara String Så här =är= det enligt MSDN Library: Hej nopes, det funkar heller inte... Hej > detta ger ett timeoutvärde på 9dagar, 8timmar och 34minuter... Hej > Håll med om att det var långsökt Hej igen , det här var en tuff djä.... Tack Thomas du har rätt. Tack som fan Thomas, du är grym! allt funkar nu!!! får luska lite i om man kan snygga till detta i VB. Tack än en gång!! >Frågan är ju bara hur man gör för att få VB att fatta att det är minnesadressen till talet du vill skicka. I och med att ingen ännu har kunnat visa hur man gör det i VB (och jag inte kan VB) så får vi istället ta och göra talet till en sträng, > Man deklarerar parametern som ByRef. Byref .. As Long eller >Jo, det tyckte ju jag också, så det föreslog jag i "början", men det funkade visst inte. > Det jag syftade på med "stringfipplande" (mycktet bra ord för övrigt) är Hej > VB gör alltid om String parametrar till API funktioner till/från ANSI. >> I min kod använder jag dock inte unicode-strängar. >Men, men, säger du att de är puckon får jag väl ta ditt ord på det.WTS API fel - LÖST
Det står att pBuffer är ett DWORD, men den tas emot som en sträng. jag tror jag testat alla möjliga kombinationer utan att lyckas. någon som kan hjälpa mig att få snurr på detta.
<code>x</code>
WTSUserConfigTimeoutSettingsConnections
A DWORD value that specifies the maximum connection duration, in milliseconds. One minute before the connection timeout interval expires, the user is notified of the pending disconnection. The user's session is disconnected or terminated depending on the WTSUserConfigBrokenTimeoutSettings value. Every time the user logs on, the timer is reset. A value of zero indicates the connection timer is disabled.
<code>
Public Declare Function TermServerConfig Lib "wtsapi32" Alias _
"WTSSetUserConfigA" (ByVal pServerName As String, _
ByVal pUserName As String, ByVal WTSConfigClass As WTS_CONFIG_CLASS, _
ByVal pBuffer As String, ByRef DataLength As Long) As Boolean
</code>Sv: WTS API fel
I C är ju det här inget problem för där typecastar man bara, dvs man berättar att DWORD:t egentligen är en sträng, så blir det det. Men hur du gör i VB för att tala om att det är en sträng har jag ingen aning om. Förhoppningsvis kanske någon annan har det nu när de vet att det är en sträng.Sv: WTS API fel
..., ByVal pBuffer As Long, ...
Om du använder den till flera olika saker kan du använda den mer generella
..., pBuffer As Any, ...
och sen anropa med
..., ByVal NåttTimeoutVärde, ...
MSSv: WTS API fel
jag ändrade till pBuffer as any och skickade in byVal x , men då fick jag minnes fel. Något annat tips, jag blir tokig snart...
För jag ska väl skicka in timeoutvärdet som ett vanligt tal eller är det hex eller binärt eller något annat skumt??Sv: WTS API fel
Testa utan ByVal.
MSSv: WTS API fel
Undrar om det inte är denna parameter som är fel
ByRef DataLength As Long .
Du kan testa att skicka den som
ByVal eller helt enkelt ett tal som är tillräckligt stort
Jag skulle testa att skicka 1024# .
Dvs detta tal exakt som det står.
Övtiga parametrar skall du skicka ByVal
pBuffer skall vara en String sk dummy
Dim buff As String
Du kan skicka buff = Space$(512)
Detta är förmodligen en retursträng som du skall läsa av.
Tror och spånar
SvenSv: WTS API fel
vad menar du med 1024# vad betyder # och vad menas med Space$(512) vad är $ ??Sv: WTS API fel
Talet du skickar på pBuffer ska vara en minnesadress. Om den minnesadressen är ogiltig eller DataLength inte stämmer så får du minnesfel.
> För jag ska väl skicka in timeoutvärdet som ett vanligt tal eller är det
> hex eller binärt eller något annat skumt??
Alla tal i datorn är binära, så det är inget du behöver tänka på.
Problemet här är ju att winapi är gjort för att användas i C och inte VB. När man vill använda det i VB blir det därför bökigt.
Men som jag har förstått av VB (kan inte så mycket VB) så ska pBuffer vara en LONG som du skickar ByRef och som innehåller timeoutvärdet. DataLength ska vara en LONG som du skickar ByVal som innehåller 4.Sv: WTS API fel
>så ska pBuffer vara en LONG .
Public Declare Function TermServerConfig Lib "wtsapi32" Alias _
"WTSSetUserConfigA" (ByVal pServerName As String, _
ByVal pUserName As String, ByVal WTSConfigClass As WTS_CONFIG_CLASS, _
ByVal pBuffer As String, ByRef DataLength As Long) As Boolean
Det köper jag inte , det står tydligt att den skall vara String
Och i C skall den vara Null Terminated.
Testa buff = Space$(512) & vbNullChar
Faen Vi ger oss inte klart att det går att anropa från VB.
Sven som har brottats med många till synes omöjliga API:ere
Problemmet ligger i DataLength .
mvh
SvenSv: WTS API fel
Hur ser din typdeklaration ut
ByVal WTSConfigClass As WTS_CONFIG_CLASS
Denna Typ måste ju vara Ok
DSSv: WTS API fel
Dim b As Boolean
Dim buff As Variant
buff = Space$(512) & vbNullChar
b = TermServerConfig("ad1utv", "olle", WTSUserConfigTimeoutSettingsConnections, buff, 1024)
är jag helt ute o cyklar?, jag får inte något minnes fel längre men hur sätter jag timeout värdet?Sv: WTS API fel
Skall fundera ett tag när du visar din Typ deklaration
Helt klart är att API är skrivet för VB och skall funka där.
1024 skall ha ett & efter sig 1024& , betecknar Long
Skrev fel i mitt förra svar
mvh
SvenSv: WTS API fel
Skulle kunna tänka mig att du har en variabel i
Typ deklarationen som heter TimeOut
Då skulle det kunna se ut så här
Label1.Caption = WTS.TimeOut
spånar
SvenSv: WTS API fel
<code>
Public Declare Function TermServerConfig Lib "wtsapi32" Alias _
"WTSSetUserConfigA" (ByVal pServerName As String, _
ByVal pUserName As String, ByVal WTSConfigClass As WTS_CONFIG_CLASS, _
ByVal pBuffer As String, ByRef DataLength As Long) As Boolean
Enum WTS_CONFIG_CLASS
WTSUserConfigInitialProgram
WTSUserConfigWorkingDirectory
WTSUserConfigfInheritInitialProgram
WTSUserConfigfAllowLogonTerminalServer
WTSUserConfigTimeoutSettingsConnections
WTSUserConfigTimeoutSettingsDisconnections
WTSUserConfigTimeoutSettingsIdle
WTSUserConfigfDeviceClientDrives
WTSUserConfigfDeviceClientPrinters
WTSUserConfigfDeviceClientDefaultPrinter
WTSUserConfigBrokenTimeoutSettings
WTSUserConfigReconnectSettings
WTSUserConfigModemCallbackSettings
WTSUserConfigModemCallbackPhoneNumber
WTSUserConfigShadowingSettings
WTSUserConfigTerminalServerProfilePath
WTSUserConfigTerminalServerHomeDir
WTSUserConfigTerminalServerHomeDirDrive
WTSUserConfigfTerminalServerRemoteHomeDir
End Enum
Public Function test()
Dim b As Boolean
Dim buff As Variant
buff = Space$(512) & vbNullChar
b = TermServerConfig("ad1utv", "olle", WTSUserConfigTimeoutSettingsConnections, buff, 1024)
End Function
</code>
så här ser det hela ut... men timeouten blir på 6dagar någonting...Sv: WTS API fel
Nej Ok , fick för mig att WTS var en Typ Deklaration
Ja du är på rätt väg hoppas någon API guru kan hjälpa dig vidare
Vad blir det för värde på buff när du kört ditt call ?
b = TermServerConfig("ad1utv", "olle", WTSUserConfigTimeoutSettingsConnections, buff, 1024)
Label1.Caption = buff Jag tror nämnligen att buff innehåller
någon form av returvärde
DSSv: WTS API fel
Sv: WTS API fel
1024& var ju bara något jag högg till med ,testa att ändra
till 0& eller något annat. 100000& kanske ?Sv: WTS API fel
Sv: WTS API fel
Hittade detta
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/termserv/tsref_9z76.asp
Skall du inte skicka TimeOut tiden i ms på den plats som
buff nu står på. Skulle kunna tänka mig "60000" & vbNullChar för en minut
spånar
SvenSv: WTS API fel
Declare Function TermServerConfig Lib "wtsapi32" Alias _
"WTSSetUserConfigA" (ByVal pServerName As String, _
ByVal pUserName As String, ByVal WTSConfigClass As WTS_CONFIG_CLASS, _
pBuffer As Any, ByVal DataLength As Long) As Long
Dim timeout As Long
timeout = 1234 ' eller nått annat lämpligt värde
Call TermServerConfig("ad1utv", "olle", WTSUserConfigTimeoutSettingsConnections, timeout, LenB(timeout))
MSSv: WTS API fel
Så är det alla gånger .Man kan skicka som any men här
passar det med Long som Thomas mycket riktigt kom fram till
DWORD täcker hela kittet
Så tror jag
mvh
SvenSv: WTS API fel
Så här då som test.
b = TermServerConfig("ad1utv", "olle", WTSUserConfigTimeoutSettingsConnections, "60000" & vbNullChar, 10)
Skall "om gud är god" ge 1 mint TimeOut
DSSv: WTS API fel
I MSDN Library står det så här: "Pointer to the data used to modify the specified user's configuration.". Dvs, det står inget om nån sträng, utan vad som finns i variabeln beror på vad man skickar på WTS_CONFIG_CLASS, dvs vilket värde man önskar ändra. Är det ett textvärde så skickar man en sträng, är det numeriskt värde (som i det här fallet) skickar man ett tal.
Dessutom ska man på DataLength ange hur många bytes värdet är.Sv: WTS API fel
Första parametern: En sträng som talar om vilken server det gäller.
Andra parametern: En sträng som talar om vilket användarnamn det gäller.
Tredje parametern: En siffra som talar om vilket värde som ska ändras (i ditt fall 4).
Fjärde parametern: En minnesadress som innehåller det nya värdet (i ditt fall ett tal, helst 32 bitar).
Femte parametern: Ett tal som anger hur många bytes det nya värdet tar upp (i ditt fall 4 om du får till ett 32-bitarstal i fjärde parametern som det ska vara).
Sen hur man skriver det här i VB har jag tyvärr ingen aning om, för jag använder bara C, och då skriver man ju bara rakt av, precis som det står i MSDN.Sv: WTS API fel
Ok så här bör det fungera
(WTSUserConfigTimeoutSettingsConnections = &H4)
Obs du skall använda denna Private Declare
I en Test Form
Private Declare Function TermServerConfig Lib "wtsapi32.dll" _
Alias "WTSSetUserConfigA" (ByVal pServerName As String, _
ByVal pUserName As String, ByVal WTSConfigClass As Long, _
ByVal pBuffer As String, ByVal pBytes As Long) As Long
Private Sub test(ByVal tOut As Long) 'TimeOut i ms
Dim ret As Long
Dim data As String
data = CStr(tOut)
ret = TermServerConfig("ad1utv", "olle", &H4, data, Len(data))
End Sub
'Call test(60000) ' ger en minuts TimeOut
Om inte detta funkar så skall det vara så här
Private Declare Function TermServerConfig Lib "wtsapi32.dll" _
Alias "WTSSetUserConfigA" (ByVal pServerName As String, _
ByVal pUserName As String, ByVal WTSConfigClass As Long, _
ByVal pBuffer As Long, ByRef pBytesReturned As Long) As Long
Private Sub test(ByVal tOut As Long) 'TimeOut i ms
Dim ret As Long
ret = TermServerConfig("ad1utv", "olle", &H4, tOut, 4&)
End Sub
SvenSv: WTS API fel
detta ger ett timeoutvärde på 9dagar, 8timmar och 34minuter...
det måste vara något major fel i detta API...
i det andra exemplet som du gav mig Sven då blev det minnes fel...
<code>
Private Declare Function TermServerConfig Lib "wtsapi32.dll" _
Alias "WTSSetUserConfigA" (ByVal pServerName As String, _
ByVal pUserName As String, ByVal WTSConfigClass As Long, _
ByVal pBuffer As String, ByVal pBytes As Long) As Long
Private Sub test(ByVal tOut As Long) 'TimeOut i ms
Dim ret As Long
Dim data As String
data = CStr(tOut)
ret = TermServerConfig("ad1utv", "olle", &H4, data, Len(data))
End Sub
Private Sub Form_Load()
Call test(60000)
End Sub
</code>Sv: WTS API fel
Det var ett djä... lurigt API. Finns det inte nån
API Guru därute som kan komma med ett tips.
Kolla den här länken hos PlanetSource sök på VB och wtsapi32
http://www.planet-source-code.com/
http://www.planet-source-code.com/vb/scripts/BrowseCategoryOrSearchResults.asp?optSort=Alphabetical&lngWId=1&B1=Quick+Search&blnWorldDropDownUsed=TRUE&txtMaxNumberOfEntriesPerPage=10&blnResetAllVariables=TRUE&txtCriteria=wtsapi32
mvh
SvenSv: WTS API fel
> det måste vara något major fel i detta API...
9 dygn, 8 timmar, 34 minuter, 24 sekunder och 432 millisekunder för att vara exakt.
Nej, det är inget fel på api-funktionen, för det stämde precis! I din kod sa du åt den att lagra 808 464 432 millisekunder, vilket var just vad den gjorde.
Felet du gör här är att du gör om värdet 60000 till en sträng (med CStr). Då får den nämligen tecknena '6', '0', '0', '0', '0'. Som du kanske känner till finns det något som heter ascii-tabell som talar om vilket värde varje tecken har (känner du inte till det kan du se det på http://www.tydal.nu/ascii.phtml ).
Värdet för tecknet '6' är 54 och värdet för '0' är 48. Det som WTSSetUserConfig förväntar sig är ett DWORD (long) som är fyra tecken. Den kommer alltså bara läsa de fyra sista tecknen som är '0', '0', '0' och '0'. Värdet för '0' är 48, och för att få fram det totala värdet räknar vi 48 * 256^3 + 48 * 256^2 + 48 * 256^1 + 48 * 256^0. Vi räknar "baklänges" eftersom det är little endian på intel.
Detta blir: 808 464 432 millisekunder vilket motsvarar det värde du fick inställt.
808464432/1000 = 808464 sekunder.
808464432%1000 = 432 millisekunder.
808464/60 = 13474 minuter.
808464%60 = 24 sekunder.
13474/60 = 224 timmar.
13474%60 = 34 minuter.
224/24 = 9 dygn.
224%24 = 8 timmar.
Totalt: 9 dygn, 8 timmar, 34 minuter, 24 sekunder och 432 millisekunder, var det värdet som du ställde in, så bli inte ledsen, för det fungerade ju. Frågan är ju bara hur man gör för att få VB att fatta att det är minnesadressen till talet du vill skicka. I och med att ingen ännu har kunnat visa hur man gör det i VB (och jag inte kan VB) så får vi istället ta och göra talet till en sträng, men då måste ju denna sträng innehålla värdet för det antal millisekunder vi vill ha och inte tecknen för det. CStr kan vi därför inte använda, utan vi får ta till lite matematiska kunskaper istället...
Ett DWORD består som jag tidigare nämnt av fyra tecken. Vårt jobb är alltså att hitta de fyra tecken som motsvarar önskat antal millisekunder. Eftersom tecken räknas hexadecimalt så måste vi använda det. Det vi också måste tänka på är att intels processorer jobbar little endian, dvs de vänder på tecknen. Om vi lagrar det hexadecimala talet 34567891 så lagras det: 91 78 56 34. Detta motsvaras av fyra tecken. Kollar vi i ascii-tabellen så ser vi att det är: ` x V 4.
Hur som helst, antalet millisekunder måste alltså göras om till fyra tecken. För att göra det måste vi göra om dem till basen 256. Jag orkar inte gå in i detalj just nu på hur man konverterar mellan baser, utan jag gör det bara...
a = Int(tOut / 16777216)
if a then
r = tOut mod 16777216
b = CInt(r / 65536)
else
b = Int(tOut / 65536)
r = tOut
end if
if a or b then
r = r mod 65536
c = Int(r / 256)
else
c = Int(tOut / 256)
r = tOut
end if
if a or b or c then
d = int(r mod 256)
else
d = tOut
end if
data = chr(d) & chr(c) & chr(b) & chr(a)
OBS! Glömde säga det först, men där du nu har Len(data) ska du istället bara sätta en fyra!Sv: WTS API fel
De va som faen..............
Håll med om att det var långsökt
Lurigt så det förslår
SvenSv: WTS API fel
> Lurigt så det förslår
Egentligen är det inte så lurigt. Funktionen vill bara ha en minnesadress som pekar på ett vanligt tal. Men eftersom ingen visste hur man får fram en minnesadress i VB var vi tvungen att hitta på en annan lösning. Ni upptäckte att det fungerade när man skickade värdet som en sträng och jag skrev därför lite kod som omvandlar talet så att VB tror att det är en sträng trots att det i själva verket är minnesadressen till ett tal.
Visst kan jag hålla med om att det känns som onormalt mycket kod för en sån sak, för det tycker jag verkligen. Motsvarande kod i C består nämligen bara av ett endaste tecken: &. Där hade jag bara skrivit &tOut så hade den skött resten själv, för det är ingen konst för datorn. Men man tillåter det inte bara rakt av i VB (kanske finns nåt annat sätt att gå runt det som jag inte känner till - jag kan ju inte VB egentligen) eftersom VB då skulle bli ett för komplext språk, för svårt att förstå.
Det är som jag brukar säga; VB är väldigt lätt att använda när man ska göra enkla saker, men väldigt svårt när man vill ha något komplicerat. C däremot håller en mer jämn nivå och är medelsvårt hela tiden, såväl till lätta saker som till svåra. Detta innebär ju att inlärningströskeln är hög, men när man kommit över den är det lugna gatan nästan oavsett vad man vill göra.Sv: WTS API fel
Kan det här funka eller har jag tänkt fel igen ?
Private Declare Function TermServerConfig Lib "wtsapi32.dll" _
Alias "WTSSetUserConfigA" (ByVal pServerName As String, _
ByVal pUserName As String, ByVal WTSConfigClass As Long, _
ByVal pBuffer As String, ByVal pBytes As Long) As Long
Private Sub test(ByVal tOut As Long) 'TimeOut i ms
Dim ret As Long
Dim data As String
data = Hex$(tOut)
ret = TermServerConfig("ad1utv", "olle", &H4, data, 4&)
End Sub
Private Sub Form_Load()
Call test(60000) 'Jag förväntar mig 1 minut
End Sub
Faen vet om det blir rätt , men det är på rätt väg.
mvh
Sven
Jag har ju inte 2000 så jag kan inte testa
Ett stort tack till Thomas som kunde reda ut logiken
DSSv: WTS API fel
Sv: WTS API fel
Man deklarerar parametern som ByRef. Byref .. As Long eller ByRef .. As Any. Bör dessutom vara bra mycket snabbare än det här strängfipplandet.
MSSv: WTS API fel
Jo, det tyckte ju jag också, så det föreslog jag i "början", men det funkade visst inte.
> Bör dessutom vara bra mycket snabbare än det här strängfipplandet.
Nej, min lösning är inget strängfipplande, utan det är heltalsoperationer, så det går snabbt som 17.
Visserligen är det onödigt jobb, men det är ju ingenting i jämförelse med VB i övrigt. VB är gjort så det ska vara lätt att programmera i och därför har ju prestandan fått stryka på foten.Sv: WTS API fel
Jag är övertygad om att det fungerar (det gör det i alla andra fall, så varför inte här). Antagligen var något annat fel, men jag kan tyvärr inte testa det här.
>Nej, min lösning är inget strängfipplande, utan det är heltalsoperationer, så det går snabbt som 17.
Det jag syftade på med "stringfipplande" (mycktet bra ord för övrigt) är att VB vid varje APi anrop konverterar stränparametrar från Unicode till ANSI, pch sedan tillbaka igen. Betydligt slöare än att bara skicka ett heltal.
>VB är gjort så det ska vara lätt att programmera i och därför har ju prestandan fått stryka på foten.
Men man behöver ju inte göra det värre än det redan är...
MSSv: WTS API fel
> att VB vid varje APi anrop konverterar stränparametrar från Unicode till
> ANSI, pch sedan tillbaka igen.
Ja, om du anropar en en api-funktion som vill ha en ansi-sträng med en unicode-sträng är det klart att den görs om. Du har kanske märkt att en del api-funktioner slutar på A? (MessageBoxA t.ex.) Det innebär att de vill ha en ansi-sträng. Om du istället använder api-funktionerna som slutar på W (MessageBoxW) så vill den ha unicode, och då behöver det ju inte göras om.
I min kod använder jag dock inte unicode-strängar. Det stod i dokumentationen att man skulle använda chrw för unicode, men chr verkade lite tvetydig så man kanske skulle använt chrb för säkerhets skull?Sv: WTS API fel
>Om du istället använder api-funktionerna som slutar på W (MessageBoxW) så vill den ha unicode, och då behöver det ju inte göras om.
Behöver inte, nej. Men det vet inte VB något om, eftersom den inte ändrar beteende efter funktiosnamnet. VB gör alltid om String parametrar till API funktioner till/från ANSI.
>I min kod använder jag dock inte unicode-strängar.
Visst gör du det. Alla VB strängar är Unicode.
MSSv: WTS API fel
>Visst gör du det. Alla VB strängar är Unicode.
Är det verkligen så ???
Hade för mig att man måste skriva StrConv("Data",vbUnicode)
Om man vill skicka som Unicode.Snacka om strul för detta API
Vi får väl sluta denna tråd för nu,men förbryllande var det !
mvh
SvenSv: WTS API fel
Intressant. Jag använder ju inte VB, men så låga tankar har jag faktiskt inte om Microsoft. Men, men, säger du att de är puckon får jag väl ta ditt ord på det.
>> I min kod använder jag dock inte unicode-strängar.
> Visst gör du det. Alla VB strängar är Unicode.
Jag sa att jag var lite osäker eftersom MSDN är lite otydlig på den punkten angående chr. Däremot är den inte otydlig vad det gäller chrb, så använder man det istället blir det inte unicode.Sv: WTS API fel
> Visst gör du det.
Nej, det gjorde jag inte. "Nordiz" hjälpte mig testa det på chatten, och resultatet blev en ansi-sträng.Sv: WTS API fel
>Är det verkligen så ???
Ja - om du vill kunna skriva ut innehållet i alla fall. Du kan ju trycka in bytedata i en sträng med ChrB eller StrConv(, vbFromUnicode), men försöker du sen skriva ut det så blir det skräp, eftersom VB tolkar det som Unicode format ändå.
MSSv: WTS API fel
Jag vet inte om jag skulle kalla dom "puckon" bara för det. Så länge det finns sätt att gå runt det, vilket det gör, så är det inget stort problem.
> Visst gör du det. Alla VB strängar är Unicode.
Kanske hae varit bättre att skriva att alla strängar hanteras som Unicode av VB. Du kan ju trycka in bytedata i den, se mitt svar till Sven. Men det förhindrar inte att VB försöker göra sin Unicode->ANSI->Unicode konvertering vid API anrop.
MS