EPPlus AutoFit() different column width on different machines - epplus

I am using EPPlus Version 4.1.0
I know this issue seems extremely weird but I have already wasted 2 days on this and any input is very very welcome!
I run the following code:
using (var package = new ExcelPackage())
{
ExcelWorksheet ws = package.Workbook.Worksheets.Add("Sheet1");
...
for (int i = ws.Dimension.Start.Column; i <= ws.Dimension.End.Column; i++)
{
ws.Column(i).AutoFit(0, 100);
ws.Column(i).Style.WrapText = ws.Column(i).Width > 60;
}
...
I run this code on several machines and the AutFit() function always returns the same value for the column width.
But on one machine the (unfortunately my new laptop) the width is completely off (i.e. 33 instead of expected 11).
Any clues how my machine setup can possibly effect this?

I hope somebody else can benefit from this, but as stated in the comments, it was actually the DPI settings of my new machine that caused this.
I have yet to find out if this actually affects the reports itself.

Related

Adding new datasources to an existing .rrd

I have a .rrd db which is collecting data from a temperature gauge. Now I have a second gauge so I'd like to add this new gauge to the existing .rrd database. I tried many times with the "rrdtool tune" command, but after that I run a "rrdtool info" on my database, and I see that there's not the last data source (another gauge) that I tried to insert.
How can I do this?
The command you need is, as you say, rrdtool tune. The documentation is available online at https://oss.oetiker.ch/rrdtool/doc/rrdtune.en.html
The ability to extend an RRA and to add or remove a DS was only added late in RRDTool 1.4. Check that you are not using an older version of RRDTool, as if you are, you will not be able to use this feature until you upgrade.
I just checked, and I see I'm using RRDTOOL 1.4 so I would not have problems. Anyway, the fact is that I used this command:
/usr/bin/rrdtool tune TEMPCucina.rrd DS:METEOTEMPEXT:GAUGE:1200:U:U RRA:AVERAGE:0.5:1:180000
I got this back from the computer:
DS[TEMPCucina] typ: GAUGE hbt: 1200 min: nan max: nan
But it seems that I'm not able to write into TEMPCucina.rrd
And if I try to perform the following command:
rrdtool info TEMPCucina.rrd
I just get the following, and it seems that no new gauge has been created
filename = "TEMPCucina.rrd"
rrd_version = "0003"
step = 60
last_update = 1510780261
header_size = 556
ds[TEMPCucina].index = 0
ds[TEMPCucina].type = "GAUGE"
ds[TEMPCucina].minimal_heartbeat = 1200
ds[TEMPCucina].min = NaN
ds[TEMPCucina].max = NaN
ds[TEMPCucina].last_ds = "18"
ds[TEMPCucina].value = 1,8000000000e+01
ds[TEMPCucina].unknown_sec = 0
rra[0].cf = "AVERAGE"
rra[0].rows = 30000
rra[0].cur_row = 1304
rra[0].pdp_per_row = 1
rra[0].xff = 0,0000000000e+00
rra[0].cdp_prep[0].value = NaN
rra[0].cdp_prep[0].unknown_datapoints = 0
(when I try to write I get this, but I don't know how to proceed at this point)
ERROR: TEMPCucina.rrd: illegal attempt to update using time 1510780527 when last update time is 1510780527 (minimum one second step)
I finally did it, but I wasn't able to use the rrdtool tune function.
I finally found here how to perform a dump of the database, how to modify it, and finally restore it to its original location (so I could also correct some data).
This is not what I was searching for, but it solved my problem so I want to share it.

NAudio WaveOut.Init takes a very long time (sometimes)

I've been using NAudio recently and for the most part I'm very happy with the library. However, I've been experiencing a very annoying intermittent issue that causes the Init method to take a very long time to execute (over 30 seconds).
Here's the code I'm using:
var waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(44100, 2);
_wavePlayer = new WaveOutEvent();
_mixingSampleProvider = new MixingSampleProvider(waveFormat)
{
ReadFully = true
};
_wavePlayer.Init(_mixingSampleProvider); // program halts here
_wavePlayer.Play();
I've also tried using WaveOut instead of WaveOutEvent and I get the same problem.
I can reproduce this issue about 1 in every 3 times or so. So it's not completely easy to reproduce but it's often enough to be very, very annoying.

To many IF's. Is there a better way?

I have this code:
If CheckBox1.Checked = True Then
My.Computer.FileSystem.RenameFile("C:\Users\mario\Desktop\Dominio\1\Pc - S.txt", "Pc - S - A.txt")
'Sleep(2000) ' to sleep for 2 second
System.Threading.Thread.Sleep(2000)
My.Computer.FileSystem.RenameFile("C:\Users\mario\Desktop\Dominio\1\Pc - S - A.txt", "Pc - S.txt")
End If
If CheckBox2.Checked = True Then
My.Computer.FileSystem.RenameFile("C:\Users\mario\Desktop\Dominio\2\Pc - S.txt", "Pc - S - A.txt")
'Sleep(2000) ' to sleep for 2 second
My.Computer.FileSystem.RenameFile("C:\Users\mario\Desktop\Dominio\2\Pc - S - A.txt", "Pc - S.txt")
End If
And it continues with another 24 if's. I need them to change the name all at the same time and then wait two seconds and change it again all at the same time.Will i need to have 48(24+24) IF's?
Explanation:
Im creating a super simple way of shuting down the computers at my school. Here is my idea(hope you can understand it)
I put a program at every computer at school (in the regestry at the startup) that does the following:
(Atencion not really in a programing language)
for(1){
sleep 1000 // wait 1 sec
if.FILE.EXISTS(\\domain\folder1\shutdown.txt) then{
do: shutdown pc // if file exist it shutdowns the pc
}
}
So what this does is if there is a file in a certain directory in the domain, it shutsdown the pc.
Im doing this for 24 pcs, so i need to shutdown them individualy, therefor the many folders.
So i could simply rename the files by hand, but for 24 pcs that is a lot of work. So im developing a aplication that asks me what pcs i want to shutdown and then does:
1: Rename file.
2: Wait 2 or more seconds (so the computers in the network have time to verify if there is such file)
3: rename back the file so when the pc restarts it doesnt shutdown again.
Did you get what im trying to do? And yes there are more orthodox ways of doing this. but this is really simple, and this is more of a test than anything. (Later will be using more proper ways of doing this and do other options over the network)
Since the only difference is a single number in the filepath, why not do something like this?
var dict = new Dictionary<CheckBox, string>();
dict.Add(CheckBox1, "1");
dict.Add(CheckBox2, "2");
//etc
foreach (var kvp in dict)
{
if(kvp.Key.Checked == true)
{
My.Computer.FileSystem.RenameFile(String.Format("C:\Users\mario\Desktop\Dominio\{0}\Pc - S.txt", kvp.Value ), "Pc - S - A.txt")
}
}
We create a generic dictionary to store the association of the checkboxes to the string/number and then loop through the dictionary, checking the values. We use a format string (you could use string concatenation instead) to insert the string/number into the filepath string.
Note, this is in C#, as I'm not a VB programmer. The syntax will likely be slightly different.
Since your intention is to remotely shut down the PC's, why not actually shut them down from your code, rather than some hackish "create files then wait 2 seconds" approach?
Again, this is C# but the translation should be pretty straightforward:
var ComputerNames = new List<string>() {"Computer1", "Computer2", "Computer3"};
foreach(var pc in ComputerNames)
{
Process.Start("shutdown","-s -m \\\\" + pc);
}

Pushing a chart to the the client using Wt

I am using server push in Wt and I am trying to push a new chart with the following code:
Wt::WApplication::UpdateLock uiLock(app);
if (uiLock){
chart_ste = new ScatterPlotExample(this,10*asf.get_outputSamplingRate());
app->triggerUpdate();
}
but it waits for the program to end and then it prints it whereas the following code in the same program pushes the word "Demokritus every 0.5 secs as it should do:
for (int i=0; i<10; i++)
{
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
Wt::WApplication::UpdateLock uiLock(app);
if (uiLock) {
showFileName = new WText(this);
showFileName->setText(boost::lexical_cast<std::string>("Demokritus"));
app->triggerUpdate();
}
}
What might be my mistake?
The documentation for triggerUpdate mentions that "The update is not immediate, and thus changes that happen after this call will equally be pushed to the client." If the changes are not immediate, it could be that the first piece of code continuously tries to push updates as fast as your CPU will allow it, so it never gets to the server because a new update overwrites the last and it begins waiting again. Try adding boost::this_thread::sleep(boost::posix_time::milliseconds(500)); to the first piece of code to see if that helps.
I've done a project once where I needed to update a chart every second with new data and had a very similar setup to yours. I put in the sleep from the start because I did not want my boost thread to use too much CPU.
Also, it is unclear if the first piece of code is in a bigger loop, if it is, you probably shouldn't make a new chart every time, but create it before hand and then update it with data. I hope some of this helps.

ReadEventLog() API fails with error code 87 on Windows Server 2008 R2 while reading Application/System/Security event logs from system

I have an MFC application which reads system (i.e. Application/System/Security) event logs on Windows Server 2008 R2 in WOW64 environment. I am facing a problem with std SDK ::ReadEventLog() function in Windows Server 2008 R2. Below I have provided the code snippet, but the same code/API works perfectly in Windows XP WOW64 & x64 environment. Error code '87' refers to "The parameter is incorrect" but according me the parameters which I passed to ::ReadEventLog() function seems to be correct.
[Code]
//BufferSize.
const int BUFFER_SIZE = 1024*10
BYTE l_bBufferSize[BUFFER_SIZE];
EVENTLOGRECORD* l_pEvntLogRecord = NULL;
l_pEvntLogRecord = (EVENTLOGRECORD *) &l_bBufferSize;
::SetLastError(0);
/*
Adjust the 'counter' to read logs. 'l_nReadRecordIndex' is mapped with the list control, e.g. on key down, 'l_nReadRecordIndex' is set as "GetCountPerPage() + 1" this is one case as their are many case.
*/
DWORD l_dwLogCounter = (GetTotalNumberOfRecords() - l_nReadRecordIndex) + 1;
//Read logs as per "nCntToReadRecords".
for(l_dwLogCounter;l_nNoOfRecTobeRead <= nCntToReadRecords;l_dwLogCounter--, l_nNoOfRecTobeRead++)
{
//Get Actual position to read.
if(0 != ::ReadEventLog( m_hEventLogHandle, EVENTLOG_SEEK_READ|EVENTLOG_FORWARDS_READ,
l_dwLogCounter, l_pEvntLogRecord, BUFFER_SIZE,
&l_dwReadBytes, &l_dwNeedBytes))
{
DWORD l_dwErrCode = 0;
l_dwErrCode = ::GetLastError(); //87 is returned
return FALSE
}
}
//Data population code
If any one is aware of similar problem or worked on the similar issue please let me know the solution. Please refer the above code snippet and let me know the following things, a) What are the incorrect parameters. b) Is their any another way to read event logs.
Thanks in advance.
--
Ganesh
It is a bug, check this entry in MS's KB http://support.microsoft.com/kb/177199